Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 50739 invoked from network); 1 Dec 2005 06:20:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 1 Dec 2005 06:20:48 -0000 Received: (qmail 7027 invoked by uid 500); 1 Dec 2005 06:17:26 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 3002 invoked by uid 500); 1 Dec 2005 06:16:57 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 587 invoked by uid 99); 1 Dec 2005 06:15:47 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 30 Nov 2005 22:12:32 -0800 Received: (qmail 43923 invoked by uid 65534); 1 Dec 2005 06:11:24 -0000 Message-ID: <20051201061124.43922.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r350181 [110/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.... Date: Thu, 01 Dec 2005 06:04:00 -0000 To: harmony-commits@incubator.apache.org From: geirm@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,551 @@ +/* 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.io.InputStream; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.security.AccessController; + +import com.ibm.oti.util.Msg; +import com.ibm.oti.util.PriviAction; + +/** + * A concrete connected-socket implementation. + */ +class PlainSocketImpl extends SocketImpl { + + // For SOCKS support. A SOCKS bind() uses the last + // host connected to in its request. + static private InetAddress lastConnectedAddress; + + static private int lastConnectedPort; + + private boolean tcpNoDelay = true; + + private Object connectLock = new Object(); + + // 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; + + /** + * Accepts a connection on the provided socket, by calling the IP stack. + * + * @param newImpl + * the socket to accept connections on + * @exception SocketException + * if an error occurs while accepting + */ + protected void accept(SocketImpl newImpl) throws IOException { + if (usingSocks()) { + ((PlainSocketImpl) newImpl).socksBind(); + ((PlainSocketImpl) newImpl).socksAccept(); + return; + } + + try { + acceptStreamSocketImpl(fd, newImpl, newImpl.fd, receiveTimeout); + } catch (InterruptedIOException e) { + throw new SocketTimeoutException(e.getMessage()); + } + newImpl.localport = getLocalPort(); + } + + /** + * Answer the number of bytes that may be read from this socket without + * blocking. This call does not block. + * + * @return int the number of bytes that may be read without blocking + * @exception SocketException + * if an error occurs while peeking + */ + + protected synchronized int available() throws IOException { + // we need to check if the input has been shutdown. If so + // we should return that there is no data to be read + if (shutdownInput == true) { + return 0; + } + return availableStreamImpl(fd); + } + + /** + * Binds this socket to the specified local host/port. Binding to the 0 port + * implies binding to any available port. By not making the assignment to + * the instVar, the getLocalPort method will lazily go to the stack and + * query for the assigned port + * + * @param anAddr + * the local machine address to bind the socket to + * @param aPort + * the port on the local machine to bind the socket to + * @exception IOException + * if an error occurs while binding + */ + protected void bind(InetAddress anAddr, int aPort) throws IOException { + if (usingSocks()) { + socksBind(); + return; + } + + PlainSocketImpl2.socketBindImpl2(fd, aPort, anAddr); + address = anAddr; + if (0 != aPort) { + localport = aPort; + } else { + localport = Socket.getSocketLocalPortImpl(fd, InetAddress + .preferIPv6Addresses()); + } + } + + /** + * Close the socket. Usage thereafter is invalid. + * + * @exception IOException + * if an error occurs while closing + */ + protected void close() throws IOException { + synchronized (fd) { + if (fd.valid()) { + if ((Socket.getSocketFlags() & Socket.FLAG_SHUTDOWN) != 0) { + try { + shutdownOutput(); + } catch (Exception e) { + } + } + Socket.socketCloseImpl(fd); + initializeSocket(); + } + } + } + + /** + * Connects this socket to the specified remote host/port. This method + * assumes the sender has verified the host with the security policy. + * + * @param aHost + * the remote host to connect to + * @param aPort + * the remote port to connect to + * @exception IOException + * if an error occurs while connecting + */ + protected void connect(String aHost, int aPort) throws IOException { + InetAddress anAddr = InetAddress.getHostByNameImpl(aHost, InetAddress + .preferIPv6Addresses()); + connect(anAddr, aPort); + } + + /** + * Connects this socket to the specified remote host address/port. + * + * @param anAddr + * the remote host address to connect to + * @param aPort + * the remote port to connect to + * @exception IOException + * if an error occurs while connecting + */ + protected void connect(InetAddress anAddr, int aPort) throws IOException { + connect(anAddr, aPort, 0); + } + + /** + * Connects this socket to the specified remote host address/port. + * + * @param anAddr + * the remote host address to connect to + * @param aPort + * the remote port to connect to + * @param timeout + * a timeout where supported. 0 means no timeout + * @exception IOException + * if an error occurs while connecting + */ + private void connect(InetAddress anAddr, int aPort, int timeout) + throws IOException { + InetAddress address = anAddr.equals(InetAddress.ANY) ? InetAddress.LOOPBACK + : anAddr; + + try { + if (streaming) { + if (usingSocks()) + socksConnect(anAddr, aPort, 0); + else { + if (timeout == 0) { + PlainSocketImpl2.connectStreamSocketImpl2(fd, aPort, + trafficClass, address); + } else { + PlainSocketImpl2.connectStreamWithTimeoutSocketImpl2( + fd, aPort, timeout, trafficClass, address); + } + } + } + } catch (ConnectException e) { + throw new ConnectException(anAddr + ":" + aPort + " - " + + e.getMessage()); + } + this.address = anAddr; + this.port = aPort; + } + + /** + * 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 streaming + * true, if the socket is type streaming + * @exception SocketException + * if an error occurs while creating the socket + */ + protected void create(boolean streaming) throws SocketException { + this.streaming = streaming; + if (streaming) { + createStreamSocketImpl(fd, Socket.preferIPv4Stack()); + } else { + createDatagramSocketImpl(fd, Socket.preferIPv4Stack()); + } + } + + protected void finalize() throws IOException { + close(); + } + + /** + * Answer the socket input stream. + * + * @return InputStream an InputStream on the socket + * @exception IOException + * thrown if an error occurs while accessing the stream + */ + protected synchronized InputStream getInputStream() throws IOException { + if (!fd.valid()) + throw new SocketException(Msg.getString("K003d")); + + return new SocketInputStream(this); + } + + /** + * Answer the nominated socket option. Receive timeouts are maintained in + * Java, rather than in the JNI code. + * + * @param optID + * the socket option to retrieve + * @return Object the option value + * @exception SocketException + * thrown if an error occurs while accessing the option + */ + 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.TCP_NODELAY + && (Socket.getSocketFlags() & Socket.TCP_NODELAY) != 0) { + return new Boolean(tcpNoDelay); + } + return result; + } + } + + /** + * Answer the socket output stream. + * + * @return OutputStream an OutputStream on the socket + * @exception IOException + * thrown if an error occurs while accessing the stream + */ + protected synchronized OutputStream getOutputStream() throws IOException { + if (!fd.valid()) + throw new SocketException(Msg.getString("K003d")); + + return new SocketOutputStream(this); + } + + /** + * Listen for connection requests on this stream socket. Incoming connection + * requests are queued, up to the limit nominated by backlog. Additional + * requests are rejected. listen() may only be invoked on stream sockets. + * + * @param backlog + * the max number of outstanding connection requests + * @exception IOException + * thrown if an error occurs while listening + */ + protected void listen(int backlog) throws IOException { + if (usingSocks()) { + // Do nothing for a SOCKS connection. The listen occurs on the + // server during the bind. + return; + } + listenStreamSocketImpl(fd, backlog); + } + + /** + * Set the nominated socket option. Receive timeouts are maintained in Java, + * rather than in the JNI code. + * + * @param optID + * the socket option to set + * @param val + * the option value + * @exception SocketException + * thrown if an error occurs while setting the option + */ + public void setOption(int optID, Object val) throws SocketException { + if (optID == SocketOptions.SO_TIMEOUT) { + receiveTimeout = ((Integer) val).intValue(); + } else { + try { + Socket.setSocketOptionImpl(fd, optID, val); + if (optID == SocketOptions.TCP_NODELAY + && (Socket.getSocketFlags() & Socket.TCP_NODELAY) != 0) + tcpNoDelay = ((Boolean) val).booleanValue(); + } catch (SocketException e) { + + // we don't through an exception for IP_TOS even if the platform + // won't let us set the requested value + if (optID != SocketOptions.IP_TOS) { + throw e; + } + } + + // 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(); + } + } + } + + /** + * Answer whether to use a SOCKS proxy. + * + * @return boolean + */ + static boolean usingSocks() { + String proxySet = (String) AccessController + .doPrivileged(new PriviAction("socksProxySet")); + if (proxySet != null) + return proxySet.toLowerCase().equals("true"); + + return AccessController.doPrivileged(new PriviAction("socksProxyHost")) != null; + } + + /** + * Get the SOCKS proxy server port. + */ + private int socksGetServerPort() { + int portValue = -1; + + String proxyPort = (String) AccessController + .doPrivileged(new PriviAction("socksProxyPort")); + + if (proxyPort != null) { + portValue = Integer.parseInt(proxyPort); + } + if (portValue < 0) + portValue = 1080; + + return portValue; + } + + /** + * Get the InetAddress of the SOCKS proxy server. + */ + private InetAddress socksGetServerAddress() throws UnknownHostException { + String proxyName = (String) AccessController + .doPrivileged(new PriviAction("socksProxyHost")); + + InetAddress anAddr = InetAddress.getHostByNameImpl(proxyName, + InetAddress.preferIPv6Addresses()); + return anAddr; + } + + /** + * Connect using a SOCKS server. + */ + private void socksConnect(InetAddress applicationServerAddress, + int applicationServerPort, int timeout) throws IOException { + try { + if (timeout == 0) { + PlainSocketImpl2.connectStreamSocketImpl2(fd, + socksGetServerPort(), trafficClass, + socksGetServerAddress()); + } else { + PlainSocketImpl2.connectStreamWithTimeoutSocketImpl2(fd, + socksGetServerPort(), timeout, trafficClass, + socksGetServerAddress()); + } + + } catch (Exception e) { + throw new SocketException(Msg.getString("K003e", e)); + } + + socksRequestConnection(applicationServerAddress, applicationServerPort); + + lastConnectedAddress = applicationServerAddress; + lastConnectedPort = applicationServerPort; + } + + /** + * Request a SOCKS connection to the application server given. If the + * request fails to complete successfully, an exception is thrown. + */ + private void socksRequestConnection(InetAddress applicationServerAddress, + int applicationServerPort) throws IOException { + socksSendRequest(Socks4Message.COMMAND_CONNECT, + applicationServerAddress, applicationServerPort); + Socks4Message reply = socksReadReply(); + if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) { + throw new IOException(reply.getErrorString(reply + .getCommandOrResult())); + } + } + + /** + * Perform an accept for a SOCKS bind. + */ + void socksAccept() throws IOException { + Socks4Message reply = socksReadReply(); + if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) { + throw new IOException(reply.getErrorString(reply + .getCommandOrResult())); + } + } + + /** + * Bind using a SOCKS server. + */ + private void socksBind() throws IOException { + try { + PlainSocketImpl2.connectStreamSocketImpl2(fd, socksGetServerPort(), + trafficClass, socksGetServerAddress()); + } catch (Exception e) { + throw new IOException(Msg.getString("K003f", e)); + } + + // There must be a connection to an application host for the bind to + // work. + if (lastConnectedAddress == null) + throw new SocketException(Msg.getString("K0040")); + + // Use the last connected address and port in the bind request. + socksSendRequest(Socks4Message.COMMAND_BIND, lastConnectedAddress, + lastConnectedPort); + Socks4Message reply = socksReadReply(); + + if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) { + throw new IOException(reply.getErrorString(reply + .getCommandOrResult())); + } + + // A peculiarity of socks 4 - if the address returned is 0, use the + // original socks server address. + if (reply.getIP() == 0) { + address = socksGetServerAddress(); + } else { + // IPv6 support not yet required as + // currently the Socks4Message.getIP() only returns int, + // so only works with IPv4 4byte addresses + byte[] replyBytes = new byte[4]; + InetAddress.intToBytes(reply.getIP(), replyBytes, 0); + address = new InetAddress(replyBytes); + } + localport = reply.getPort(); + } + + /** + * Send a SOCKS V4 request. + */ + private void socksSendRequest(int command, InetAddress address, int port) + throws IOException { + Socks4Message request = new Socks4Message(); + request.setCommandOrResult(command); + request.setPort(port); + request.setIP(address.getAddress()); + request.setUserId("default"); + + getOutputStream().write(request.getBytes(), 0, request.getLength()); + } + + /** + * Read a SOCKS V4 reply. + */ + private Socks4Message socksReadReply() throws IOException { + Socks4Message reply = new Socks4Message(); + int bytesRead = 0; + while (bytesRead < Socks4Message.REPLY_LENGTH) { + bytesRead += getInputStream().read(reply.getBytes(), bytesRead, + Socks4Message.REPLY_LENGTH - bytesRead); + } + return reply; + } + + /** + * Connect the socket to the host/port specified by the SocketAddress with a + * specified timeout. + * + * + * @param remoteAddr + * the remote machine address and port to connect to + * @param timeout + * the millisecond timeout value, the connect will block + * indefinitely for a zero value. + * + * @exception IOException + * if a problem occurs during the connect + */ + protected void connect(SocketAddress remoteAddr, int timeout) + throws IOException { + InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr; + connect(inetAddr.getAddress(), inetAddr.getPort(), timeout); + } + + /** + * Answer if the socket supports urgent data. + */ + protected boolean supportsUrgentData() { + return !streaming || SocketImpl.supportsUrgentDataImpl(fd); + } + + /** + * Send the single byte of urgent data on the socket. + * + * @param value + * the byte of urgent data + * + * @exception IOException + * when an error occurs sending urgent data + */ + protected void sendUrgentData(int value) throws IOException { + SocketImpl.sendUrgentDataImpl(fd, (byte) value); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl2.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl2.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl2.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainSocketImpl2.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,144 @@ +/* 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; + +/** + * This class was added so we can create sockets without options that were + * needed for server sockets. It just overrides create so that we call new + * natives which only set the options required for plain 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 PlainSocketImpl2 extends PlainSocketImpl { + + /** + * Answer the result of attempting to create a stream socket in the IP + * stack. This version does not set certain options which were required for + * server sockets and which the initial vesrion ended up setting for both + * socket and serverSockets as the same method was used to create a socket + * for both. We have added a new method so that we can preserve the behavior + * of earlier versions + * + * @param aFD + * the socket FileDescriptor + * @exception SocketException + * if an error occurs while creating the socket + */ + static native void createStreamSocketImpl2(FileDescriptor aFD, + boolean preferIPv4Stack) throws SocketException; + + /** + * Connect the underlying socket to the nominated remotehost/port. + * + * @param aFD + * the socket FileDescriptor + * @param aport + * the remote machine port to connect to + * @param trafficClass + * the traffic class to be used when connecting + * @param inetAddress + * the address to connect to + * @exception SocketException + * if an error occurs while connecting + */ + static native void connectStreamSocketImpl2(FileDescriptor aFD, int aport, + int trafficClass, InetAddress inetAddress) throws IOException; + + /** + * Connect the underlying socket to the nominated remotehost/port. + * + * @param aFD + * the socket FileDescriptor + * @param aport + * the remote machine port to connect to + * @param timeout + * timeout after which SocketTimeoutException will be thrown + * @param trafficClass + * the traffic class to be used when connecting + * @param inetAddress + * the address to connect to + * @exception SocketException + * if an error occurs while connecting + * @exception SocketTimeoutException + * if a timeout occurs while trying to connect + */ + static native void connectStreamWithTimeoutSocketImpl2(FileDescriptor aFD, + int aport, int timeout, int trafficClass, InetAddress inetAddress) + throws IOException; + + /** + * 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) { + createStreamSocketImpl2(fd, Socket.preferIPv4Stack()); + } else { + createDatagramSocketImpl(fd, Socket.preferIPv4Stack()); + } + } + + /** + * Send the data to the nominated target address + * and port. 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 length + * the length of the data buffer in the packet + * @param port + * the target host port + * @param inetAddress + * the address to send the datagram on + * + * @exception IOException + * upon an read error or timeout + */ + static native int sendDatagramImpl2(FileDescriptor fd, byte[] data, + int offset, int length, int port, InetAddress inetAddress) + throws IOException; + + /** + * Bind the socket to the port/localhost in the IP stack. + * + * @param aFD + * the socket descriptor + * @param port + * the option selector + * @param inetAddress + * the address to be used + * + * @throws SocketException + * if bind operation fails + */ + static native void socketBindImpl2(FileDescriptor aFD, int port, + InetAddress inetAddress) throws SocketException; +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PortUnreachableException.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PortUnreachableException.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PortUnreachableException.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PortUnreachableException.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,37 @@ +/* Copyright 2004, 2004 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; + + +public class PortUnreachableException extends SocketException { + + /** + * Constructs a new instance of this class with its walkback filled in. + */ + public PortUnreachableException() { + } + + /** + * Constructs a new instance of this class with its walkback and message + * filled in. + * + * @param detailMessage + * String The detail message for the exception. + */ + public PortUnreachableException(String detailMessage) { + super(detailMessage); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ProtocolException.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ProtocolException.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ProtocolException.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ProtocolException.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,45 @@ +/* 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; + + +/** + * An attempt to connect to a socket of the wrong type (stream or nonstream) + * will trigger this exception. An invalid operation applied on the protocol + * that doesn't support it will also throw this exception. + * + * @see URL + */ +public class ProtocolException extends java.io.IOException { + + /** + * Constructs a new instance of this class with its walkback filled in. + */ + public ProtocolException() { + 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 ProtocolException(String detailMessage) { + super(detailMessage); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ServerSocket.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ServerSocket.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ServerSocket.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/ServerSocket.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,481 @@ +/* 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 com.ibm.oti.util.Msg; + +/** + * ServerSocket create connections between 'host' and 'client' machines. The + * ServerSocket listens on a well known port and upon a connection request, + * instantiates a 'host' sockets, which carries on future communication with the + * requesting 'client' socket, so that the server socket may continue listening + * for connection requests. They are passive objects, having no execution thread + * of their own to listen on. + */ +public class ServerSocket { + + SocketImpl impl; + + static SocketImplFactory factory; + + private volatile boolean isCreated = false; + + private boolean isBound = false; + + private boolean isClosed = false; + + /** + * Construct a ServerSocket, which is not bound to any port. The default + * number of pending connections may be backlogged. + * + * @see Socket + */ + public ServerSocket() throws IOException { + impl = factory != null ? factory.createSocketImpl() + : new PlainServerSocketImpl(); + } + + /** + * Construct a ServerSocket, bound to the nominated port on the default + * localhost. The default number of pending connections may be backlogged. + * + * @param aport + * the port number to listen for connection requests on + * @see Socket + */ + public ServerSocket(int aport) throws IOException { + this(aport, defaultBacklog(), InetAddress.ANY); + } + + /** + * Construct a ServerSocket, bound to the nominated port on the default + * localhost. The number of pending connections that may be backlogged is a + * specified. + * + * @param aport + * the port number to listen for connection requests on + * @param backlog + * the number of pending connection requests, before requests are + * rejected + * @see Socket + */ + public ServerSocket(int aport, int backlog) throws IOException { + this(aport, backlog, InetAddress.ANY); + } + + /** + * Construct a ServerSocket, bound to the nominated local host/port. The + * number of pending connections that may be backlogged is a specified. + * + * @param aport + * the port number to listen for connection requests on + * @param localAddr + * the local machine address to bind on + * @param backlog + * the number of pending connection requests, before requests are + * rejected + * @see Socket + */ + public ServerSocket(int aport, int backlog, InetAddress localAddr) + throws IOException { + super(); + checkListen(aport); + impl = factory != null ? factory.createSocketImpl() + : new PlainServerSocketImpl(); + InetAddress addr = localAddr == null ? InetAddress.ANY : localAddr; + + synchronized (this) { + impl.create(true); + isCreated = true; + try { + impl.bind(addr, aport); + isBound = true; + impl.listen(backlog > 0 ? backlog : defaultBacklog()); + } catch (IOException e) { + close(); + throw e; + } + } + } + + /** + * Retrieve the first connection request and answer the 'host' socket that + * will conduct further communications with the requesting 'client' socket. + * + * @return Socket the 'host' socket + * @exception IOException + * if an error occurs while instantiating the 'host' socket + */ + public Socket accept() throws IOException { + checkClosedAndCreate(false); + if (!isBound()) + throw new SocketException(Msg.getString("K031f")); + + // If a SOCKS proxy is being used, accept does strange things. + // Instead of returning a new Socket and allowing this ServerSocket + // to be used for another accept, it actually uses the current + // ServerSocket + // as the accepted Socket. So, closing the returned socket will close + // the + // ServerSocket as well. The ServerSocket cannot be used for a second + // accept. + if (PlainSocketImpl.usingSocks()) { + if (impl instanceof PlainSocketImpl) { + try { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkAccept(getInetAddress().getHostName(), + getLocalPort()); + } + } catch (SecurityException e) { + close(); + throw e; + } + + ((PlainSocketImpl) impl).socksAccept(); + return new Socket(impl); + } + + throw new IOException(Msg.getString("K0041")); //$NON-NLS-1$ + } + + Socket aSocket = new Socket(); + try { + synchronized (this) { + implAccept(aSocket); + } + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkAccept(aSocket.getInetAddress().getHostName(), + aSocket.getPort()); + } + } catch (SecurityException e) { + aSocket.close(); + throw e; + } catch (IOException e) { + aSocket.close(); + throw e; + } + return aSocket; + } + + /** + * Check whether the server may listen for connection requests on + * aport. Throw an exception if the port is outside the + * valid range or does not satisfy the security policy. + * + * @param aPort + * the candidate port to listen on + */ + void checkListen(int aPort) { + if (aPort < 0 || aPort > 65535) + throw new IllegalArgumentException(Msg.getString("K0325", aPort)); //$NON-NLS-1$ + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkListen(aPort); + } + + /** + * Close this server socket. Any attempt to connect to this socket + * thereafter will fail. + */ + public void close() throws IOException { + isClosed = true; + impl.close(); + } + + /** + * Answer the default number of pending connections on a server socket. + * + * @return int the default number of pending connection requests + */ + static int defaultBacklog() { + return 50; + } + + /** + * Answer the local IP address for this server socket. Return null if the + * socket is not bound. This is useful on multihomed hosts. + * + * @return InetAddress the local address + */ + public InetAddress getInetAddress() { + if (!isBound()) + return null; + return impl.getInetAddress(); + } + + /** + * Answer the local port for this server socket. Return -1 if the socket is + * not bound. + * + * @return int the local port the server is listening on + */ + public int getLocalPort() { + if (!isBound()) + return -1; + return impl.getLocalPort(); + } + + /** + * Answer the time-out period of this server socket. This is the time the + * server will wait listening for connections, before exiting. + * + * @return int the listening timeout + * @exception SocketException + * thrown if option cannot be retrieved + */ + public synchronized int getSoTimeout() throws IOException { + checkClosedAndCreate(true); + return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue(); + } + + /** + * Invoke the server socket implementation to accept a connection on the + * newly created aSocket. + * + * @param aSocket + * the concrete socketImpl to accept the connection request on + * @exception IOException + * thrown if connection cannot be accepted + */ + protected final void implAccept(Socket aSocket) throws IOException { + impl.accept(aSocket.impl); + aSocket.accepted(); + } + + /** + * Set the server socket implementation factory. This method may only be + * invoked with sufficient security and only once during the application + * lifetime. + * + * @param aFactory + * the streaming socket factory to be used for further socket + * instantiations + * @exception IOException + * thrown if the factory is already set + */ + public static synchronized void setSocketFactory(SocketImplFactory aFactory) + throws IOException { + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkSetFactory(); + if (factory == null) + factory = aFactory; + else + throw new SocketException(Msg.getString("K0042")); //$NON-NLS-1$ + } + + /** + * Set the listen time-out period for this server socket. + * + * @param timeout + * the time to wait for a connection request + * @exception SocketException + * thrown if an error occurs during setting the option + */ + public synchronized void setSoTimeout(int timeout) throws SocketException { + checkClosedAndCreate(true); + if (timeout >= 0) { + impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout)); + } else { + throw new IllegalArgumentException(Msg.getString("K0036")); //$NON-NLS-1$ + } + } + + /** + * Answers a string containing a concise, human-readable description of the + * server socket. The port field is reported a zero, as there + * is no connection formed to the server. + * + * @return String the description + */ + public String toString() { + StringBuffer result = new StringBuffer(64); + result.append("ServerSocket["); //$NON-NLS-1$ + if (!isBound()) + return result.append("unbound]").toString(); //$NON-NLS-1$ + return result.append("addr="). //$NON-NLS-1$ + append(getInetAddress()).append(",port=0,localport="). //$NON-NLS-1$ + append(getLocalPort()).append("]"). //$NON-NLS-1$ + toString(); + } + + /** + * Bind the ServerSocket to the nominated local host/port. The default + * number of pending connections may be backlogged. + * + * @param localAddr + * the local machine address and port to bind on + * + * @exception IllegalArgumentException + * if the SocketAddress is not supported + * @exception IOException + * if the socket is already bound, or a problem occurs during + * the bind + */ + public void bind(SocketAddress localAddr) throws IOException { + bind(localAddr, defaultBacklog()); + } + + /** + * Bind the ServerSocket to the nominated local host/port. The number of + * pending connections that may be backlogged is a specified. + * + * @param localAddr + * the local machine address and port to bind on + * @param backlog + * the number of pending connection requests, before requests are + * rejected + * + * @exception IllegalArgumentException + * if the SocketAddress is not supported + * @exception IOException + * if the socket is already bound, or a problem occurs during + * the bind + */ + public void bind(SocketAddress localAddr, int backlog) throws IOException { + checkClosedAndCreate(true); + if (isBound()) + throw new BindException(Msg.getString("K0315")); //$NON-NLS-1$ + int port = 0; + InetAddress addr = InetAddress.ANY; + if (localAddr != null) { + if (!(localAddr instanceof InetSocketAddress)) + throw new IllegalArgumentException(Msg.getString( + "K0316", localAddr.getClass())); //$NON-NLS-1$ + InetSocketAddress inetAddr = (InetSocketAddress) localAddr; + if ((addr = inetAddr.getAddress()) == null) + throw new SocketException(Msg.getString( + "K0317", inetAddr.getHostName())); //$NON-NLS-1$ + port = inetAddr.getPort(); + } + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkListen(port); + + synchronized (this) { + try { + impl.bind(addr, port); + isBound = true; + impl.listen(backlog > 0 ? backlog : defaultBacklog()); + } catch (IOException e) { + close(); + throw e; + } + } + } + + /** + * Answer the local SocketAddress for this server socket, or null if the + * socket is not bound. This is useful on multihomed hosts. + */ + public SocketAddress getLocalSocketAddress() { + if (!isBound()) + return null; + return new InetSocketAddress(getInetAddress(), getLocalPort()); + } + + /** + * Return if the server socket is bound to a local address and port. + */ + public boolean isBound() { + return isBound; + } + + /** + * Return if the server socket is closed. + */ + public boolean isClosed() { + return isClosed; + } + + /** + * Check if the socket is closed, and throw an exception. + */ + private void checkClosedAndCreate(boolean create) throws SocketException { + if (isClosed()) + throw new SocketException(Msg.getString("K003d")); + + if (!create || isCreated) + return; + + synchronized (this) { + if (isCreated) + return; + try { + impl.create(true); + } catch (SocketException e) { + throw e; + } catch (IOException e) { + throw new SocketException(e.toString()); + } + isCreated = true; + } + } + + /** + * Set the SO_REUSEADDR socket option. + * + * @param reuse + * the socket SO_REUSEADDR option setting + */ + public void setReuseAddress(boolean reuse) throws SocketException { + checkClosedAndCreate(true); + impl.setOption(SocketOptions.SO_REUSEADDR, reuse ? Boolean.TRUE + : Boolean.FALSE); + } + + /** + * Get the state of the SO_REUSEADDR socket option. + */ + public boolean getReuseAddress() throws SocketException { + checkClosedAndCreate(true); + return ((Boolean) impl.getOption(SocketOptions.SO_REUSEADDR)) + .booleanValue(); + } + + /** + * Set the socket receive buffer size. + * + * @param size + * the buffer size, in bytes + * + * @exception java.net.SocketException + * If an error occurs while setting the size or the size is + * invalid. + */ + public void setReceiveBufferSize(int size) throws SocketException { + checkClosedAndCreate(true); + if (size >= 1) + impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size)); + else + throw new IllegalArgumentException(Msg.getString("K0035")); //$NON-NLS-1$ + } + + /** + * Answer the socket receive buffer size (SO_RCVBUF). + * + * @return int socket receive buffer size + */ + public int getReceiveBufferSize() throws SocketException { + checkClosedAndCreate(true); + return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue(); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/Socket.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/Socket.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/Socket.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/Socket.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,1043 @@ +/* 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.InputStream; +import java.io.OutputStream; +import java.security.AccessController; + +import com.ibm.oti.util.Msg; +import com.ibm.oti.util.PriviAction; + +/** + * This class represents sockets to be used in connection-oriented (streaming) + * protocols. + */ +public class Socket { + + SocketImpl impl; + + static SocketImplFactory factory; + + private volatile boolean isCreated = false; + + private boolean isBound = false; + + private boolean isConnected = false; + + private boolean isClosed = false; + + private boolean isInputShutdown = false; + + private boolean isOutputShutdown = false; + + private Object connectLock = new Object(); + + static final int MULTICAST_IF = 1; + + static final int MULTICAST_TTL = 2; + + static final int TCP_NODELAY = 4; + + static final int FLAG_SHUTDOWN = 8; + + // Fill in the JNI id caches + + private static native void oneTimeInitialization(boolean jcl_supports_ipv6); + + static { + oneTimeInitialization(true); + } + + /** + * Construct a connection-oriented Socket. The Socket is created in the + * factory if declared, or otherwise of the default type. + * + * @see SocketImplFactory + */ + public Socket() { + impl = factory != null ? factory.createSocketImpl() + : new PlainSocketImpl2(); + } + + /** + * Construct a stream socket connected to the nominated destination + * host/port. By default, the socket binds it to any available port on the + * default localhost. + * + * @param dstName + * the destination host to connect to + * @param dstPort + * the port on the destination host to connect to + * + * @throws UnknownHostException + * if the host cannot be resolved + * @throws IOException + * if an error occurs while instantiating the socket + */ + public Socket(String dstName, int dstPort) throws UnknownHostException, + IOException { + this(); + InetAddress dstAddress = InetAddress.getByName(dstName); + checkDestination(dstAddress, dstPort); + startupSocket(dstAddress, dstPort, null, 0, true); + } + + /** + * Construct a stream socket connected to the nominated destination + * host/port. The socket is bound it to the nominated localAddress/port. + * + * @param dstName + * the destination host to connect to + * @param dstPort + * the port on the destination host to connect to + * @param localAddress + * the local host address to bind to + * @param localPort + * the local port to bind to + * + * @throws UnknownHostException + * if the host cannot be resolved + * @throws IOException + * if an error occurs while instantiating the socket + */ + public Socket(String dstName, int dstPort, InetAddress localAddress, + int localPort) throws IOException { + this(); + InetAddress dstAddress = InetAddress.getByName(dstName); + checkDestination(dstAddress, dstPort); + startupSocket(dstAddress, dstPort, localAddress, localPort, true); + } + + /** + * Answer a new socket. This constructor is deprecated. + * + * @param hostName + * the host name + * @param port + * the port on the host + * @param streaming + * if true, answer a stream socket, else answer a a datagram + * socket. + * + * @throws UnknownHostException + * if the host cannot be resolved + * @throws IOException + * if an error occurs while instantiating the socket + * + * @deprecated As of JDK 1.1, replaced by Socket + * @see #Socket(String,int) + */ + public Socket(String hostName, int port, boolean streaming) + throws IOException { + this(); + InetAddress host = InetAddress.getByName(hostName); + checkDestination(host, port); + startupSocket(host, port, null, 0, streaming); + } + + /** + * Construct a stream socket connected to the nominated destination host + * address/port. By default, the socket binds it to any available port on + * the default localhost. + * + * @param dstAddress + * the destination host address to connect to + * @param dstPort + * the port on the destination host to connect to + * + * @throws IOException + * if an error occurs while instantiating the socket + */ + public Socket(InetAddress dstAddress, int dstPort) throws IOException { + this(); + checkDestination(dstAddress, dstPort); + startupSocket(dstAddress, dstPort, null, 0, true); + } + + /** + * Construct a stream socket connected to the nominated destination host + * address/port. The socket is bound it to the nominated localAddress/port. + * + * @param dstAddress + * the destination host address to connect to + * @param dstPort + * the port on the destination host to connect to + * @param localAddress + * the local host address to bind to + * @param localPort + * the local port to bind to + * + * @throws IOException + * if an error occurs while instantiating the socket + */ + public Socket(InetAddress dstAddress, int dstPort, + InetAddress localAddress, int localPort) throws IOException { + this(); + checkDestination(dstAddress, dstPort); + startupSocket(dstAddress, dstPort, localAddress, localPort, true); + } + + /** + * Answer a new socket. This constructor is deprecated. + * + * @param addr + * the internet address + * @param port + * the port on the host + * @param streaming + * if true, answer a stream socket, else answer a datagram + * socket. + * + * @throws UnknownHostException + * if the host cannot be resolved + * @throws IOException + * if an error occurs while instantiating the socket + * + * @deprecated As of JDK 1.1, replaced by Socket + * @see #Socket(InetAddress,int) + */ + public Socket(InetAddress addr, int port, boolean streaming) + throws IOException { + this(); + checkDestination(addr, port); + startupSocket(addr, port, null, 0, streaming); + } + + /** + * Creates an unconnected socket, wrapping the socketImpl + * argument. + * + * @param anImpl + * the socket to wrap + * + * @throws SocketException + * if an error occurs assigning the implementation + */ + protected Socket(SocketImpl anImpl) throws SocketException { + impl = anImpl; + } + + /** + * Check the connection destination satisfies the security policy and is in + * the valid port range. + * + * @param destAddr + * the destination host address + * @param dstPort + * the port on the destination host + */ + void checkDestination(InetAddress destAddr, int dstPort) { + if (dstPort < 0 || dstPort > 65535) + throw new IllegalArgumentException(Msg.getString("K0032")); + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkConnect(destAddr.getHostName(), dstPort); + } + + /** + * Close the socket. It is not valid to use the socket thereafter. + * + * @throws IOException + * if an error occurs during the close + */ + public synchronized void close() throws IOException { + isClosed = true; + impl.close(); + } + + /** + * Returns an {@link InetAddress} instance representing the address this + * socket has connected to. + * + * @return if this socket is connected, the address it is connected to. A + * null return signifies no connection has been made. + */ + public InetAddress getInetAddress() { + if (!isConnected()) + return null; + return impl.getInetAddress(); + } + + /** + * Answer the socket input stream, to read byte data off the socket. Note, + * multiple input streams may be created on a single socket. + * + * @return a byte oriented read stream for this socket + * + * @throws IOException + * if an error occurs creating the stream + * + * @see java.net.SocketInputStream + */ + public InputStream getInputStream() throws IOException { + checkClosedAndCreate(false); + if (isInputShutdown()) + throw new SocketException(Msg.getString("K0321")); + return impl.getInputStream(); + } + + /** + * Answer the SO_KEEPALIVE option for this socket. + * + * @return the socket SO_KEEPALIVE option setting + * + * @throws SocketException + * if an error occurs on the option access + */ + public boolean getKeepAlive() throws SocketException { + checkClosedAndCreate(true); + return ((Boolean) impl.getOption(SocketOptions.SO_KEEPALIVE)) + .booleanValue(); + } + + /** + * Returns an {@link InetAddress} instance representing the local + * address this socket is bound to. + * + * @return the local address that this socket has bound to + */ + public InetAddress getLocalAddress() { + if (!isBound()) + return InetAddress.ANY; + return Socket.getSocketLocalAddressImpl(impl.fd, InetAddress + .preferIPv6Addresses()); + } + + /** + * Answer the local port to which the socket is bound. + * + * @return the local port to which the socket is bound + */ + public int getLocalPort() { + if (!isBound()) + return -1; + return impl.getLocalPort(); + } + + /** + * Answer the socket output stream, for writing byte data on the socket. + * Note, multiplie output streams may be created on a single socket. + * + * @return OutputStream a byte oriented write stream for this socket + * + * @throws IOException + * if an error occurs creating the stream + * + * @see java.net.SocketOutputStream + */ + public OutputStream getOutputStream() throws IOException { + checkClosedAndCreate(false); + return impl.getOutputStream(); + } + + /** + * Returns the number of the remote port this socket is connected to. + * + * @return int the remote port number that this socket has connected to. A + * return of 0 (zero) indicates that there is no + * connection in place. + */ + public int getPort() { + if (!isConnected()) + return 0; + return impl.getPort(); + } + + /** + * Answer the linger-on-close timeout for this socket (the SO_LINGER value). + * + * @return this socket's SO_LINGER value. A value of -1 will + * be returned if the option is not enabled. + * + * @throws SocketException + * if an error occurs on querying this property + */ + public int getSoLinger() throws SocketException { + checkClosedAndCreate(true); + return ((Integer) impl.getOption(SocketOptions.SO_LINGER)).intValue(); + } + + /** + * Answer the socket receive buffer size (SO_RCVBUF). + * + * @return socket receive buffer size + * + * @throws SocketException + * if an error occurs on the option access + */ + public synchronized int getReceiveBufferSize() throws SocketException { + checkClosedAndCreate(true); + return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue(); + } + + /** + * Answer the socket send buffer size (SO_SNDBUF). + * + * @return socket send buffer size + * + * @throws SocketException + * if an error occurs on the option access + */ + public synchronized int getSendBufferSize() throws SocketException { + checkClosedAndCreate(true); + return ((Integer) impl.getOption(SocketOptions.SO_SNDBUF)).intValue(); + } + + /** + * Answer the socket read timeout. The SO_TIMEOUT option, a value of 0 + * indicates it is disabled and a read operation will block indefinitely + * waiting for data. + * + * @return the socket read timeout + * + * @throws SocketException + * if an error occurs on the option access + */ + public synchronized int getSoTimeout() throws SocketException { + checkClosedAndCreate(true); + return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue(); + } + + /** + * Answer true if the socket is using Nagle's algorithm. The TCP_NODELAY + * option setting. + * + * @return the socket TCP_NODELAY option setting + * + * @throws SocketException + * if an error occurs on the option access + */ + public boolean getTcpNoDelay() throws SocketException { + checkClosedAndCreate(true); + return ((Boolean) impl.getOption(SocketOptions.TCP_NODELAY)) + .booleanValue(); + } + + static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD, + boolean preferIPv6Addresses); + + /** + * Query the IP stack for the local port to which this socket is bound. + * + * @param aFD + * the socket descriptor + * @param preferIPv6Addresses + * address preference for nodes that support both IPv4 and IPv6 + * @return int the local port to which the socket is bound + */ + static native int getSocketLocalPortImpl(FileDescriptor aFD, + boolean preferIPv6Addresses); + + /** + * Query the IP stack for the nominated socket option. + * + * @param aFD + * the socket descriptor + * @param opt + * the socket option type + * @return the nominated socket option value + * + * @throws SocketException + * if the option is invalid + */ + static native Object getSocketOptionImpl(FileDescriptor aFD, int opt) + throws SocketException; + + /** + * Set the nominated socket option in the IP stack. + * + * @param aFD + * the socket descriptor + * @param opt + * the option selector + * @param optVal + * the nominated option value + * + * @throws SocketException + * if the option is invalid or cannot be set + */ + static native void setSocketOptionImpl(FileDescriptor aFD, int opt, + Object optVal) throws SocketException; + + /** + * Set the SO_KEEPALIVE option for this socket. + * + * @param value + * the socket SO_KEEPALIVE option setting + * + * @throws SocketException + * if an error occurs setting the option + */ + public void setKeepAlive(boolean value) throws SocketException { + checkClosedAndCreate(true); + impl.setOption(SocketOptions.SO_KEEPALIVE, value ? Boolean.TRUE + : Boolean.FALSE); + } + + static native int getSocketFlags(); + + /** + * Close the socket in the IP stack. + * + * @param aFD + * the socket descriptor + */ + static native void socketCloseImpl(FileDescriptor aFD); + + /** + * Specifies the application's socket implementation factory. This may only + * be executed the once over the lifetime of the application. + * + * @param fac + * the socket factory to set + * @exception IOException + * thrown if the factory has already been set + */ + public static synchronized void setSocketImplFactory(SocketImplFactory fac) + throws IOException { + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkSetFactory(); + if (factory == null) + factory = fac; + else + throw new SocketException(Msg.getString("K0044")); + } + + /** + * Set the socket send buffer size. + * + * @param size + * the buffer size, in bytes + * + * @throws SocketException + * if an error occurs while setting the size or the size is + * invalid. + */ + public synchronized void setSendBufferSize(int size) throws SocketException { + checkClosedAndCreate(true); + if (size >= 1) + impl.setOption(SocketOptions.SO_SNDBUF, new Integer(size)); + else + throw new IllegalArgumentException(Msg.getString("K0035")); + } + + /** + * Set the socket receive buffer size. + * + * @param size + * the buffer size, in bytes + * + * @throws SocketException + * tf an error occurs while setting the size or the size is + * invalid. + */ + public synchronized void setReceiveBufferSize(int size) + throws SocketException { + checkClosedAndCreate(true); + if (size >= 1) + impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size)); + else + throw new IllegalArgumentException(Msg.getString("K0035")); + } + + /** + * Set the SO_LINGER option, with the specified time, in seconds. The + * SO_LINGER option is silently limited to 65535 seconds. + * + * @param on + * if linger is enabled + * @param timeout + * the linger timeout value, in seconds + * + * @throws SocketException + * if an error occurs setting the option + */ + public void setSoLinger(boolean on, int timeout) throws SocketException { + checkClosedAndCreate(true); + if (!on || 0 <= timeout) { + int val = on ? (65535 < timeout ? 65535 : timeout) : -1; + impl.setOption(SocketOptions.SO_LINGER, new Integer(val)); + } else + throw new IllegalArgumentException(Msg.getString("K0045")); + } + + /** + * Set the read timeout on this socket. The SO_TIMEOUT option, is specified + * in milliseconds. The read operation will block indefinitely for a zero + * value. + * + * @param timeout + * the read timeout value + * + * @throws SocketException + * if an error occurs setting the option + */ + public synchronized void setSoTimeout(int timeout) throws SocketException { + checkClosedAndCreate(true); + if (timeout >= 0) + impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout)); + else + throw new IllegalArgumentException(Msg.getString("K0036")); + } + + /** + * Set whether the socket is to use Nagle's algorithm. The TCP_NODELAY + * option setting. + * + * @param on + * the socket TCP_NODELAY option setting + * + * @throws SocketException + * if an error occurs setting the option + */ + public void setTcpNoDelay(boolean on) throws SocketException { + checkClosedAndCreate(true); + impl.setOption(SocketOptions.TCP_NODELAY, new Boolean(on)); + } + + /** + * Creates a stream socket, binds it to the nominated local address/port, + * then connects it to the nominated destination address/port. + * + * @param dstAddress + * the destination host address + * @param dstPort + * the port on the destination host + * @param localAddress + * the address on the local machine to bind + * @param localPort + * the port on the local machine to bind + * + * @throws IOException + * thrown if a error occurs during the bind or connect + * operations + */ + void startupSocket(InetAddress dstAddress, int dstPort, + InetAddress localAddress, int localPort, boolean streaming) + throws IOException { + if (localPort < 0 || localPort > 65535) + throw new IllegalArgumentException(Msg.getString("K0046")); + + InetAddress addr = localAddress == null ? InetAddress.ANY + : localAddress; + synchronized (this) { + impl.create(streaming); + isCreated = true; + try { + if (!streaming || !PlainSocketImpl.usingSocks()) + impl.bind(addr, localPort); + isBound = true; + impl.connect(dstAddress, dstPort); + isConnected = true; + } catch (IOException e) { + impl.close(); + throw e; + } + } + } + + /** + * Answers a string containing a concise, human-readable description of the + * socket. + * + * @return the description + */ + public String toString() { + if (!isConnected()) + return "Socket[unconnected]"; //$NON-NLS-1$ + return impl.toString(); + } + + /** + * Shutdown the input portion of the socket. + * + * @throws IOException + * if an error occurs while closing the socket input + * @throws SocketException + * if the socket is closed + */ + public void shutdownInput() throws IOException { + checkClosedAndCreate(false); + impl.shutdownInput(); + isInputShutdown = true; + } + + /** + * Shutdown the output portion of the socket. + * + * @throws IOException + * if an error occurs while closing the socket output + * @throws SocketException + * if the socket is closed + */ + public void shutdownOutput() throws IOException { + checkClosedAndCreate(false); + impl.shutdownOutput(); + isOutputShutdown = true; + } + + /** + * Check if the socket is closed, and throw an exception. Otherwise create + * the underlying SocketImpl. + * + * @throws SocketException + * if the socket is closed + */ + private void checkClosedAndCreate(boolean create) throws SocketException { + if (isClosed()) + throw new SocketException(Msg.getString("K003d")); + if (!create) { + if (!isConnected()) + throw new SocketException(Msg.getString("K0320")); + // a connected socket must be created + } + if (isCreated) + return; + synchronized (this) { + if (isCreated) + return; + try { + impl.create(true); + } catch (SocketException e) { + throw e; + } catch (IOException e) { + throw new SocketException(e.toString()); + } + isCreated = true; + } + } + + /** + * Answer the local SocketAddress for this socket, or null if the socket is + * not bound. + *

+ * This is useful on multihomed hosts. + * + * @return the local socket address + */ + public SocketAddress getLocalSocketAddress() { + if (!isBound()) + return null; + return new InetSocketAddress(getLocalAddress(), getLocalPort()); + } + + /** + * Answer the remote SocketAddress for this socket, or null if the socket is + * not connected. + * + * @return the remote socket address + */ + public SocketAddress getRemoteSocketAddress() { + if (!isConnected()) + return null; + return new InetSocketAddress(getInetAddress(), getPort()); + } + + /** + * Return if the socket is bound to a local address and port. + * + * @return true if the socket is bound to a local address, + * false otherwise. + */ + public boolean isBound() { + return isBound; + } + + /** + * Return if the socket is connected. + * + * @return true if the socket is connected, + * false otherwise. + */ + public boolean isConnected() { + return isConnected; + } + + /** + * Return if the socket is closed. + * + * @return true if the socket is closed, false + * otherwise. + */ + public boolean isClosed() { + return isClosed; + } + + /** + * Bind the Socket to the nominated local host/port. + * + * @param localAddr + * the local machine address and port to bind on + * + * @throws IllegalArgumentException + * if the SocketAddress is not supported + * @throws IOException + * if the socket is already bound, or a problem occurs during + * the bind + */ + public void bind(SocketAddress localAddr) throws IOException { + checkClosedAndCreate(true); + if (isBound()) + throw new BindException(Msg.getString("K0315")); //$NON-NLS-1$ + + int port = 0; + InetAddress addr = InetAddress.ANY; + if (localAddr != null) { + if (!(localAddr instanceof InetSocketAddress)) + throw new IllegalArgumentException(Msg.getString( + "K0316", localAddr.getClass())); //$NON-NLS-1$ + InetSocketAddress inetAddr = (InetSocketAddress) localAddr; + if ((addr = inetAddr.getAddress()) == null) + throw new SocketException(Msg.getString( + "K0317", inetAddr.getHostName())); //$NON-NLS-1$ + port = inetAddr.getPort(); + } + + synchronized (this) { + try { + if (!PlainSocketImpl.usingSocks()) + impl.bind(addr, port); + isBound = true; + } catch (IOException e) { + impl.close(); + throw e; + } + } + } + + /** + * Connect the Socket to the host/port specified by the SocketAddress. + * + * @param remoteAddr + * the remote machine address and port to connect to + * + * @throws IllegalArgumentException + * if the SocketAddress is not supported + * @throws IOException + * if the socket is already connected, or a problem occurs + * during the connect + */ + public void connect(SocketAddress remoteAddr) throws IOException { + connect(remoteAddr, 0); + } + + /** + * Connect the Socket to the host/port specified by the SocketAddress with a + * specified timeout. + * + * @param remoteAddr + * the remote machine address and port to connect to + * @param timeout + * the millisecond timeout value, the connect will block + * indefinitely for a zero value. + * + * @throws IllegalArgumentException + * if the timeout is negative, or the SocketAddress is not + * supported + * @throws IOException + * if the socket is already connected, or a problem occurs + * during the connect + */ + public void connect(SocketAddress remoteAddr, int timeout) + throws IOException { + checkClosedAndCreate(true); + if (timeout < 0) + throw new IllegalArgumentException(Msg.getString("K0036")); + if (isConnected()) + throw new SocketException(Msg.getString("K0079")); //$NON-NLS-1$ + if (remoteAddr == null) + throw new IllegalArgumentException(Msg.getString("K0318")); + + if (!(remoteAddr instanceof InetSocketAddress)) + throw new IllegalArgumentException(Msg.getString( + "K0316", remoteAddr.getClass())); //$NON-NLS-1$ + InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr; + InetAddress addr; + if ((addr = inetAddr.getAddress()) == null) + throw new SocketException(Msg.getString( + "K0317", inetAddr.getHostName())); //$NON-NLS-1$ + int port = inetAddr.getPort(); + + checkDestination(addr, port); + synchronized (connectLock) { + try { + if (!isBound()) { + // socket allready created at this point by earlier call or + // checkClosedAndCreate + // this caused us to lose socket options on create + // impl.create(true); + if (!PlainSocketImpl.usingSocks()) + impl.bind(InetAddress.ANY, 0); + isBound = true; + } + impl.connect(remoteAddr, timeout); + isConnected = true; + } catch (IOException e) { + impl.close(); + throw e; + } + } + } + + /** + * Return if {@link #shutdownInput} has been called. + * + * @return true if shutdownInput has been + * called, false otherwise. + */ + public boolean isInputShutdown() { + return isInputShutdown; + } + + /** + * Return if {@link #shutdownOutput} has been called. + * + * @return true if shutdownOutput has been + * called, false otherwise. + */ + public boolean isOutputShutdown() { + return isOutputShutdown; + } + + /** + * Set the SO_REUSEADDR socket option. + * + * @param reuse + * the socket SO_REUSEADDR option setting + * + * @throws SocketException + * if the socket is closed or the option is invalid. + */ + public void setReuseAddress(boolean reuse) throws SocketException { + checkClosedAndCreate(true); + impl.setOption(SocketOptions.SO_REUSEADDR, reuse ? Boolean.TRUE + : Boolean.FALSE); + } + + /** + * Get the state of the SO_REUSEADDR socket option. + * + * @return true if the SO_REUSEADDR is enabled, + * false otherwise. + * + * @throws SocketException + * if the socket is closed or the option is invalid. + */ + public boolean getReuseAddress() throws SocketException { + checkClosedAndCreate(true); + return ((Boolean) impl.getOption(SocketOptions.SO_REUSEADDR)) + .booleanValue(); + } + + /** + * Set the SO_OOBINLINE socket option. When this option is enabled, out of + * band data is recieved in the normal data stream. + * + * @param oobinline + * the socket SO_OOBINLINE option setting + * + * @throws SocketException + * if the socket is closed or the option is invalid. + */ + public void setOOBInline(boolean oobinline) throws SocketException { + checkClosedAndCreate(true); + impl.setOption(SocketOptions.SO_OOBINLINE, oobinline ? Boolean.TRUE + : Boolean.FALSE); + } + + /** + * Get the state of the SO_OOBINLINE socket option. + * + * @return true if the SO_OOBINLINE is enabled, + * false otherwise. + * + * @throws SocketException + * if the socket is closed or the option is invalid. + */ + public boolean getOOBInline() throws SocketException { + checkClosedAndCreate(true); + return ((Boolean) impl.getOption(SocketOptions.SO_OOBINLINE)) + .booleanValue(); + } + + /** + * Set the IP_TOS socket option. + * + * @param value + * the socket IP_TOS setting + * + * @throws SocketException + * if the socket is closed or the option is invalid. + */ + public void setTrafficClass(int value) throws SocketException { + checkClosedAndCreate(true); + if (value < 0 || value > 255) + throw new IllegalArgumentException(); + impl.setOption(SocketOptions.IP_TOS, new Integer(value)); + } + + /** + * Get the IP_TOS socket option. + * + * @return the IP_TOS socket option value + * + * @throws SocketException + * if the option is invalid + */ + public int getTrafficClass() throws SocketException { + checkClosedAndCreate(true); + return ((Number) impl.getOption(SocketOptions.IP_TOS)).intValue(); + } + + /** + * Send the single byte of urgent data on the socket. + * + * @param value + * the byte of urgent data + * + * @exception IOException + * when an error occurs sending urgent data + */ + public void sendUrgentData(int value) throws IOException { + if (!impl.supportsUrgentData()) { + throw new SocketException(Msg.getString("K0333")); + } + impl.sendUrgentData(value); + } + + /** + * Set the appropriate flags for a Socket created by ServerSocket.accept(). + * + * @see ServerSocket#implAccept + */ + void accepted() { + isCreated = isBound = isConnected = true; + } + + static boolean preferIPv4Stack() { + String result = (String) AccessController.doPrivileged(new PriviAction( + "java.net.preferIPv4Stack")); + if ("true".equals(result)) + return true; + return false; + } + +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketAddress.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketAddress.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketAddress.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketAddress.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,26 @@ +/* Copyright 2004, 2004 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.Serializable; + +public abstract class SocketAddress implements Serializable { + + public SocketAddress() { + super(); + } +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketException.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketException.java?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketException.java (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/SocketException.java Wed Nov 30 21:29:27 2005 @@ -0,0 +1,45 @@ +/* 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; + + +import java.io.IOException; + +/** + * This SocketException may be thrown during socket creation or setting options, + * and is the superclass of all other socket related exceptions. + */ +public class SocketException extends IOException { + + /** + * Constructs a new instance of this class with its walkback filled in. + */ + public SocketException() { + 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 SocketException(String detailMessage) { + super(detailMessage); + } + +}