1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package java.net;
28
29import java.io.FileDescriptor;
30import java.io.InputStream;
31import java.io.OutputStream;
32import java.io.IOException;
33import java.io.InterruptedIOException;
34import java.nio.channels.SocketChannel;
35import java.security.AccessController;
36import java.security.PrivilegedExceptionAction;
37import java.security.PrivilegedAction;
38
39/**
40 * This class implements client sockets (also called just
41 * "sockets"). A socket is an endpoint for communication
42 * between two machines.
43 * <p>
44 * The actual work of the socket is performed by an instance of the
45 * <code>SocketImpl</code> class. An application, by changing
46 * the socket factory that creates the socket implementation,
47 * can configure itself to create sockets appropriate to the local
48 * firewall.
49 *
50 * @author  unascribed
51 * @see     java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
52 * @see     java.net.SocketImpl
53 * @see     java.nio.channels.SocketChannel
54 * @since   JDK1.0
55 */
56public
57class Socket implements java.io.Closeable {
58    /**
59     * Various states of this socket.
60     */
61    private boolean created = false;
62    private boolean bound = false;
63    private boolean connected = false;
64    private boolean closed = false;
65    private Object closeLock = new Object();
66    private boolean shutIn = false;
67    private boolean shutOut = false;
68
69    /**
70     * The implementation of this Socket.
71     */
72    SocketImpl impl;
73
74    /**
75     * Are we using an older SocketImpl?
76     */
77    private boolean oldImpl = false;
78
79    /**
80     * Creates an unconnected socket, with the
81     * system-default type of SocketImpl.
82     *
83     * @since   JDK1.1
84     * @revised 1.4
85     */
86    public Socket() {
87        setImpl();
88    }
89
90    /**
91     * Creates an unconnected socket, specifying the type of proxy, if any,
92     * that should be used regardless of any other settings.
93     * <P>
94     * If there is a security manager, its <code>checkConnect</code> method
95     * is called with the proxy host address and port number
96     * as its arguments. This could result in a SecurityException.
97     * <P>
98     * Examples:
99     * <UL> <LI><code>Socket s = new Socket(Proxy.NO_PROXY);</code> will create
100     * a plain socket ignoring any other proxy configuration.</LI>
101     * <LI><code>Socket s = new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("socks.mydom.com", 1080)));</code>
102     * will create a socket connecting through the specified SOCKS proxy
103     * server.</LI>
104     * </UL>
105     *
106     * @param proxy a {@link java.net.Proxy Proxy} object specifying what kind
107     *              of proxying should be used.
108     * @throws IllegalArgumentException if the proxy is of an invalid type
109     *          or <code>null</code>.
110     * @throws SecurityException if a security manager is present and
111     *                           permission to connect to the proxy is
112     *                           denied.
113     * @see java.net.ProxySelector
114     * @see java.net.Proxy
115     *
116     * @since   1.5
117     */
118    public Socket(Proxy proxy) {
119        // Create a copy of Proxy as a security measure
120        if (proxy == null) {
121            throw new IllegalArgumentException("Invalid Proxy");
122        }
123        Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy);
124        if (p.type() == Proxy.Type.SOCKS) {
125            SecurityManager security = System.getSecurityManager();
126            InetSocketAddress epoint = (InetSocketAddress) p.address();
127            if (epoint.getAddress() != null) {
128                checkAddress (epoint.getAddress(), "Socket");
129            }
130            if (security != null) {
131                if (epoint.isUnresolved())
132                    epoint = new InetSocketAddress(epoint.getHostName(), epoint.getPort());
133                if (epoint.isUnresolved())
134                    security.checkConnect(epoint.getHostName(), epoint.getPort());
135                else
136                    security.checkConnect(epoint.getAddress().getHostAddress(),
137                                  epoint.getPort());
138            }
139            impl = new SocksSocketImpl(p);
140            impl.setSocket(this);
141        } else {
142            if (p == Proxy.NO_PROXY) {
143                if (factory == null) {
144                    impl = new PlainSocketImpl();
145                    impl.setSocket(this);
146                } else
147                    setImpl();
148            } else
149                throw new IllegalArgumentException("Invalid Proxy");
150        }
151    }
152
153    /**
154     * Creates an unconnected Socket with a user-specified
155     * SocketImpl.
156     * <P>
157     * @param impl an instance of a <B>SocketImpl</B>
158     * the subclass wishes to use on the Socket.
159     *
160     * @exception SocketException if there is an error in the underlying protocol,
161     * such as a TCP error.
162     * @since   JDK1.1
163     */
164    protected Socket(SocketImpl impl) throws SocketException {
165        this.impl = impl;
166        if (impl != null) {
167            checkOldImpl();
168            this.impl.setSocket(this);
169        }
170    }
171
172    /**
173     * Creates a stream socket and connects it to the specified port
174     * number on the named host.
175     * <p>
176     * If the specified host is <tt>null</tt> it is the equivalent of
177     * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
178     * In other words, it is equivalent to specifying an address of the
179     * loopback interface. </p>
180     * <p>
181     * If the application has specified a server socket factory, that
182     * factory's <code>createSocketImpl</code> method is called to create
183     * the actual socket implementation. Otherwise a "plain" socket is created.
184     * <p>
185     * If there is a security manager, its
186     * <code>checkConnect</code> method is called
187     * with the host address and <code>port</code>
188     * as its arguments. This could result in a SecurityException.
189     *
190     * @param      host   the host name, or <code>null</code> for the loopback address.
191     * @param      port   the port number.
192     *
193     * @exception  UnknownHostException if the IP address of
194     * the host could not be determined.
195     *
196     * @exception  IOException  if an I/O error occurs when creating the socket.
197     * @exception  SecurityException  if a security manager exists and its
198     *             <code>checkConnect</code> method doesn't allow the operation.
199     * @exception  IllegalArgumentException if the port parameter is outside
200     *             the specified range of valid port values, which is between
201     *             0 and 65535, inclusive.
202     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
203     * @see        java.net.SocketImpl
204     * @see        java.net.SocketImplFactory#createSocketImpl()
205     * @see        SecurityManager#checkConnect
206     */
207    public Socket(String host, int port)
208        throws UnknownHostException, IOException
209    {
210        this(InetAddress.getAllByName(host), port, (SocketAddress) null, true);
211    }
212
213    /**
214     * Creates a stream socket and connects it to the specified port
215     * number at the specified IP address.
216     * <p>
217     * If the application has specified a socket factory, that factory's
218     * <code>createSocketImpl</code> method is called to create the
219     * actual socket implementation. Otherwise a "plain" socket is created.
220     * <p>
221     * If there is a security manager, its
222     * <code>checkConnect</code> method is called
223     * with the host address and <code>port</code>
224     * as its arguments. This could result in a SecurityException.
225     *
226     * @param      address   the IP address.
227     * @param      port      the port number.
228     * @exception  IOException  if an I/O error occurs when creating the socket.
229     * @exception  SecurityException  if a security manager exists and its
230     *             <code>checkConnect</code> method doesn't allow the operation.
231     * @exception  IllegalArgumentException if the port parameter is outside
232     *             the specified range of valid port values, which is between
233     *             0 and 65535, inclusive.
234     * @exception  NullPointerException if <code>address</code> is null.
235     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
236     * @see        java.net.SocketImpl
237     * @see        java.net.SocketImplFactory#createSocketImpl()
238     * @see        SecurityManager#checkConnect
239     */
240    public Socket(InetAddress address, int port) throws IOException {
241        this(nonNullAddress(address), port, (SocketAddress) null, true);
242    }
243
244    /**
245     * Creates a socket and connects it to the specified remote host on
246     * the specified remote port. The Socket will also bind() to the local
247     * address and port supplied.
248     * <p>
249     * If the specified host is <tt>null</tt> it is the equivalent of
250     * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
251     * In other words, it is equivalent to specifying an address of the
252     * loopback interface. </p>
253     * <p>
254     * A local port number of <code>zero</code> will let the system pick up a
255     * free port in the <code>bind</code> operation.</p>
256     * <p>
257     * If there is a security manager, its
258     * <code>checkConnect</code> method is called
259     * with the host address and <code>port</code>
260     * as its arguments. This could result in a SecurityException.
261     *
262     * @param host the name of the remote host, or <code>null</code> for the loopback address.
263     * @param port the remote port
264     * @param localAddr the local address the socket is bound to, or
265     *        <code>null</code> for the <code>anyLocal</code> address.
266     * @param localPort the local port the socket is bound to, or
267     *        <code>zero</code> for a system selected free port.
268     * @exception  IOException  if an I/O error occurs when creating the socket.
269     * @exception  SecurityException  if a security manager exists and its
270     *             <code>checkConnect</code> method doesn't allow the operation.
271     * @exception  IllegalArgumentException if the port parameter or localPort
272     *             parameter is outside the specified range of valid port values,
273     *             which is between 0 and 65535, inclusive.
274     * @see        SecurityManager#checkConnect
275     * @since   JDK1.1
276     */
277    public Socket(String host, int port, InetAddress localAddr,
278                  int localPort) throws IOException {
279        this(InetAddress.getAllByName(host), port,
280             new InetSocketAddress(localAddr, localPort), true);
281    }
282
283    /**
284     * Creates a socket and connects it to the specified remote address on
285     * the specified remote port. The Socket will also bind() to the local
286     * address and port supplied.
287     * <p>
288     * If the specified local address is <tt>null</tt> it is the equivalent of
289     * specifying the address as the AnyLocal address (see <tt>{@link java.net.InetAddress#isAnyLocalAddress InetAddress.isAnyLocalAddress}()</tt>).
290     * <p>
291     * A local port number of <code>zero</code> will let the system pick up a
292     * free port in the <code>bind</code> operation.</p>
293     * <p>
294     * If there is a security manager, its
295     * <code>checkConnect</code> method is called
296     * with the host address and <code>port</code>
297     * as its arguments. This could result in a SecurityException.
298     *
299     * @param address the remote address
300     * @param port the remote port
301     * @param localAddr the local address the socket is bound to, or
302     *        <code>null</code> for the <code>anyLocal</code> address.
303     * @param localPort the local port the socket is bound to or
304     *        <code>zero</code> for a system selected free port.
305     * @exception  IOException  if an I/O error occurs when creating the socket.
306     * @exception  SecurityException  if a security manager exists and its
307     *             <code>checkConnect</code> method doesn't allow the operation.
308     * @exception  IllegalArgumentException if the port parameter or localPort
309     *             parameter is outside the specified range of valid port values,
310     *             which is between 0 and 65535, inclusive.
311     * @exception  NullPointerException if <code>address</code> is null.
312     * @see        SecurityManager#checkConnect
313     * @since   JDK1.1
314     */
315    public Socket(InetAddress address, int port, InetAddress localAddr,
316                  int localPort) throws IOException {
317        this(nonNullAddress(address), port,
318             new InetSocketAddress(localAddr, localPort), true);
319    }
320
321    /**
322     * Creates a stream socket and connects it to the specified port
323     * number on the named host.
324     * <p>
325     * If the specified host is <tt>null</tt> it is the equivalent of
326     * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
327     * In other words, it is equivalent to specifying an address of the
328     * loopback interface. </p>
329     * <p>
330     * If the stream argument is <code>true</code>, this creates a
331     * stream socket. If the stream argument is <code>false</code>, it
332     * creates a datagram socket.
333     * <p>
334     * If the application has specified a server socket factory, that
335     * factory's <code>createSocketImpl</code> method is called to create
336     * the actual socket implementation. Otherwise a "plain" socket is created.
337     * <p>
338     * If there is a security manager, its
339     * <code>checkConnect</code> method is called
340     * with the host address and <code>port</code>
341     * as its arguments. This could result in a SecurityException.
342     * <p>
343     * If a UDP socket is used, TCP/IP related socket options will not apply.
344     *
345     * @param      host     the host name, or <code>null</code> for the loopback address.
346     * @param      port     the port number.
347     * @param      stream   a <code>boolean</code> indicating whether this is
348     *                      a stream socket or a datagram socket.
349     * @exception  IOException  if an I/O error occurs when creating the socket.
350     * @exception  SecurityException  if a security manager exists and its
351     *             <code>checkConnect</code> method doesn't allow the operation.
352     * @exception  IllegalArgumentException if the port parameter is outside
353     *             the specified range of valid port values, which is between
354     *             0 and 65535, inclusive.
355     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
356     * @see        java.net.SocketImpl
357     * @see        java.net.SocketImplFactory#createSocketImpl()
358     * @see        SecurityManager#checkConnect
359     * @deprecated Use DatagramSocket instead for UDP transport.
360     */
361    @Deprecated
362    public Socket(String host, int port, boolean stream) throws IOException {
363        this(InetAddress.getAllByName(host), port, (SocketAddress) null, stream);
364    }
365
366    /**
367     * Creates a socket and connects it to the specified port number at
368     * the specified IP address.
369     * <p>
370     * If the stream argument is <code>true</code>, this creates a
371     * stream socket. If the stream argument is <code>false</code>, it
372     * creates a datagram socket.
373     * <p>
374     * If the application has specified a server socket factory, that
375     * factory's <code>createSocketImpl</code> method is called to create
376     * the actual socket implementation. Otherwise a "plain" socket is created.
377     *
378     * <p>If there is a security manager, its
379     * <code>checkConnect</code> method is called
380     * with <code>host.getHostAddress()</code> and <code>port</code>
381     * as its arguments. This could result in a SecurityException.
382     * <p>
383     * If UDP socket is used, TCP/IP related socket options will not apply.
384     *
385     * @param      host     the IP address.
386     * @param      port      the port number.
387     * @param      stream    if <code>true</code>, create a stream socket;
388     *                       otherwise, create a datagram socket.
389     * @exception  IOException  if an I/O error occurs when creating the socket.
390     * @exception  SecurityException  if a security manager exists and its
391     *             <code>checkConnect</code> method doesn't allow the operation.
392     * @exception  IllegalArgumentException if the port parameter is outside
393     *             the specified range of valid port values, which is between
394     *             0 and 65535, inclusive.
395     * @exception  NullPointerException if <code>host</code> is null.
396     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
397     * @see        java.net.SocketImpl
398     * @see        java.net.SocketImplFactory#createSocketImpl()
399     * @see        SecurityManager#checkConnect
400     * @deprecated Use DatagramSocket instead for UDP transport.
401     */
402    @Deprecated
403    public Socket(InetAddress host, int port, boolean stream) throws IOException {
404        this(nonNullAddress(host), port, new InetSocketAddress(0), stream);
405    }
406
407    private static InetAddress[] nonNullAddress(InetAddress address) {
408        // backward compatibility
409        if (address == null)
410            throw new NullPointerException();
411
412        return new InetAddress[] { address };
413    }
414
415    // Android-changed: Socket ctor should try all addresses
416    // b/30007735
417    private Socket(InetAddress[] addresses, int port, SocketAddress localAddr,
418            boolean stream) throws IOException {
419        if (addresses == null || addresses.length == 0) {
420            throw new SocketException("Impossible: empty address list");
421        }
422
423        for (int i = 0; i < addresses.length; i++) {
424            setImpl();
425            try {
426                InetSocketAddress address = new InetSocketAddress(addresses[i], port);
427                createImpl(stream);
428                if (localAddr != null) {
429                    bind(localAddr);
430                }
431                connect(address);
432                break;
433            } catch (IOException | IllegalArgumentException | SecurityException e) {
434                try {
435                    // Android-changed:
436                    // Do not call #close, classes that extend this class may do not expect a call
437                    // to #close coming from the superclass constructor.
438                    impl.close();
439                    closed = true;
440                } catch (IOException ce) {
441                    e.addSuppressed(ce);
442                }
443
444                // Only stop on the last address.
445                if (i == addresses.length - 1) {
446                    throw e;
447                }
448            }
449
450            // Discard the connection state and try again.
451            impl = null;
452            created = false;
453            bound = false;
454            closed = false;
455        }
456    }
457
458    /**
459     * Creates the socket implementation.
460     *
461     * @param stream a <code>boolean</code> value : <code>true</code> for a TCP socket,
462     *               <code>false</code> for UDP.
463     * @throws IOException if creation fails
464     * @since 1.4
465     */
466     void createImpl(boolean stream) throws SocketException {
467        if (impl == null)
468            setImpl();
469        try {
470            impl.create(stream);
471            created = true;
472        } catch (IOException e) {
473            throw new SocketException(e.getMessage());
474        }
475    }
476
477    private void checkOldImpl() {
478        if (impl == null)
479            return;
480        // SocketImpl.connect() is a protected method, therefore we need to use
481        // getDeclaredMethod, therefore we need permission to access the member
482
483        oldImpl = AccessController.doPrivileged
484                                (new PrivilegedAction<Boolean>() {
485            public Boolean run() {
486                Class[] cl = new Class[2];
487                cl[0] = SocketAddress.class;
488                cl[1] = Integer.TYPE;
489                Class clazz = impl.getClass();
490                while (true) {
491                    try {
492                        clazz.getDeclaredMethod("connect", cl);
493                        return Boolean.FALSE;
494                    } catch (NoSuchMethodException e) {
495                        clazz = clazz.getSuperclass();
496                        // java.net.SocketImpl class will always have this abstract method.
497                        // If we have not found it by now in the hierarchy then it does not
498                        // exist, we are an old style impl.
499                        if (clazz.equals(java.net.SocketImpl.class)) {
500                            return Boolean.TRUE;
501                        }
502                    }
503                }
504            }
505        });
506    }
507
508    /**
509     * Sets impl to the system-default type of SocketImpl.
510     * @since 1.4
511     */
512    void setImpl() {
513        if (factory != null) {
514            impl = factory.createSocketImpl();
515            checkOldImpl();
516        } else {
517            // No need to do a checkOldImpl() here, we know it's an up to date
518            // SocketImpl!
519            impl = new SocksSocketImpl();
520        }
521        if (impl != null)
522            impl.setSocket(this);
523    }
524
525
526    /**
527     * Get the <code>SocketImpl</code> attached to this socket, creating
528     * it if necessary.
529     *
530     * @return  the <code>SocketImpl</code> attached to that ServerSocket.
531     * @throws SocketException if creation fails
532     * @since 1.4
533     */
534    SocketImpl getImpl() throws SocketException {
535        if (!created)
536            createImpl(true);
537        return impl;
538    }
539
540    /**
541     * Connects this socket to the server.
542     *
543     * @param   endpoint the <code>SocketAddress</code>
544     * @throws  IOException if an error occurs during the connection
545     * @throws  java.nio.channels.IllegalBlockingModeException
546     *          if this socket has an associated channel,
547     *          and the channel is in non-blocking mode
548     * @throws  IllegalArgumentException if endpoint is null or is a
549     *          SocketAddress subclass not supported by this socket
550     * @since 1.4
551     * @spec JSR-51
552     */
553    public void connect(SocketAddress endpoint) throws IOException {
554        connect(endpoint, 0);
555    }
556
557    /**
558     * Connects this socket to the server with a specified timeout value.
559     * A timeout of zero is interpreted as an infinite timeout. The connection
560     * will then block until established or an error occurs.
561     *
562     * @param   endpoint the <code>SocketAddress</code>
563     * @param   timeout  the timeout value to be used in milliseconds.
564     * @throws  IOException if an error occurs during the connection
565     * @throws  SocketTimeoutException if timeout expires before connecting
566     * @throws  java.nio.channels.IllegalBlockingModeException
567     *          if this socket has an associated channel,
568     *          and the channel is in non-blocking mode
569     * @throws  IllegalArgumentException if endpoint is null or is a
570     *          SocketAddress subclass not supported by this socket
571     * @since 1.4
572     * @spec JSR-51
573     */
574    public void connect(SocketAddress endpoint, int timeout) throws IOException {
575        if (endpoint == null)
576            throw new IllegalArgumentException("connect: The address can't be null");
577
578        if (timeout < 0)
579          throw new IllegalArgumentException("connect: timeout can't be negative");
580
581        if (isClosed())
582            throw new SocketException("Socket is closed");
583
584        if (!oldImpl && isConnected())
585            throw new SocketException("already connected");
586
587        if (!(endpoint instanceof InetSocketAddress))
588            throw new IllegalArgumentException("Unsupported address type");
589
590        InetSocketAddress epoint = (InetSocketAddress) endpoint;
591        InetAddress addr = epoint.getAddress ();
592        int port = epoint.getPort();
593        checkAddress(addr, "connect");
594
595        SecurityManager security = System.getSecurityManager();
596        if (security != null) {
597            if (epoint.isUnresolved())
598                security.checkConnect(epoint.getHostName(), port);
599            else
600                security.checkConnect(addr.getHostAddress(), port);
601        }
602        if (!created)
603            createImpl(true);
604        if (!oldImpl)
605            impl.connect(epoint, timeout);
606        else if (timeout == 0) {
607            if (epoint.isUnresolved())
608                impl.connect(addr.getHostName(), port);
609            else
610                impl.connect(addr, port);
611        } else
612            throw new UnsupportedOperationException("SocketImpl.connect(addr, timeout)");
613        connected = true;
614        /*
615         * If the socket was not bound before the connect, it is now because
616         * the kernel will have picked an ephemeral port & a local address
617         */
618        bound = true;
619    }
620
621    /**
622     * Binds the socket to a local address.
623     * <P>
624     * If the address is <code>null</code>, then the system will pick up
625     * an ephemeral port and a valid local address to bind the socket.
626     *
627     * @param   bindpoint the <code>SocketAddress</code> to bind to
628     * @throws  IOException if the bind operation fails, or if the socket
629     *                     is already bound.
630     * @throws  IllegalArgumentException if bindpoint is a
631     *          SocketAddress subclass not supported by this socket
632     *
633     * @since   1.4
634     * @see #isBound
635     */
636    public void bind(SocketAddress bindpoint) throws IOException {
637        if (isClosed())
638            throw new SocketException("Socket is closed");
639        if (!oldImpl && isBound())
640            throw new SocketException("Already bound");
641
642        if (bindpoint != null && (!(bindpoint instanceof InetSocketAddress)))
643            throw new IllegalArgumentException("Unsupported address type");
644        InetSocketAddress epoint = (InetSocketAddress) bindpoint;
645        if (epoint != null && epoint.isUnresolved())
646            throw new SocketException("Unresolved address");
647        if (epoint == null) {
648            epoint = new InetSocketAddress(0);
649        }
650        InetAddress addr = epoint.getAddress();
651        int port = epoint.getPort();
652        checkAddress (addr, "bind");
653        getImpl().bind (addr, port);
654        bound = true;
655    }
656
657    private void checkAddress (InetAddress addr, String op) {
658        if (addr == null) {
659            return;
660        }
661        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
662            throw new IllegalArgumentException(op + ": invalid address type");
663        }
664    }
665
666    /**
667     * set the flags after an accept() call.
668     */
669    final void postAccept() {
670        connected = true;
671        created = true;
672        bound = true;
673    }
674
675    void setCreated() {
676        created = true;
677    }
678
679    void setBound() {
680        bound = true;
681    }
682
683    void setConnected() {
684        connected = true;
685    }
686
687    /**
688     * Returns the address to which the socket is connected.
689     * <p>
690     * If the socket was connected prior to being {@link #close closed},
691     * then this method will continue to return the connected address
692     * after the socket is closed.
693     *
694     * @return  the remote IP address to which this socket is connected,
695     *          or <code>null</code> if the socket is not connected.
696     */
697    public InetAddress getInetAddress() {
698        if (!isConnected())
699            return null;
700        try {
701            return getImpl().getInetAddress();
702        } catch (SocketException e) {
703        }
704        return null;
705    }
706
707    /**
708     * Gets the local address to which the socket is bound.
709     *
710     * @return the local address to which the socket is bound, or
711     *         the {@link InetAddress#isAnyLocalAddress wildcard} address
712     *         if the socket is closed or not bound yet.
713     * @since   JDK1.1
714     */
715    public InetAddress getLocalAddress() {
716        // This is for backward compatibility
717        if (!isBound())
718            return InetAddress.anyLocalAddress();
719        InetAddress in = null;
720        try {
721            in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
722
723            if (!NetUtil.doRevealLocalAddress()) {
724                SecurityManager sm = System.getSecurityManager();
725                if (sm != null)
726                    sm.checkConnect(in.getHostAddress(), -1);
727            }
728            if (in.isAnyLocalAddress()) {
729                in = InetAddress.anyLocalAddress();
730            }
731        } catch (SecurityException e) {
732            in = InetAddress.getLoopbackAddress();
733        } catch (Exception e) {
734            in = InetAddress.anyLocalAddress(); // "0.0.0.0"
735        }
736        return in;
737    }
738
739    /**
740     * Returns the remote port number to which this socket is connected.
741     * <p>
742     * If the socket was connected prior to being {@link #close closed},
743     * then this method will continue to return the connected port number
744     * after the socket is closed.
745     *
746     * @return  the remote port number to which this socket is connected, or
747     *          0 if the socket is not connected yet.
748     */
749    public int getPort() {
750        if (!isConnected())
751            return 0;
752        try {
753            return getImpl().getPort();
754        } catch (SocketException e) {
755            // Shouldn't happen as we're connected
756        }
757        return -1;
758    }
759
760    /**
761     * Returns the local port number to which this socket is bound.
762     * <p>
763     * If the socket was bound prior to being {@link #close closed},
764     * then this method will continue to return the local port number
765     * after the socket is closed.
766     *
767     * @return  the local port number to which this socket is bound or -1
768     *          if the socket is not bound yet.
769     */
770    public int getLocalPort() {
771        if (!isBound())
772            return -1;
773        try {
774            return getImpl().getLocalPort();
775        } catch(SocketException e) {
776            // shouldn't happen as we're bound
777        }
778        return -1;
779    }
780
781    /**
782     * Returns the address of the endpoint this socket is connected to, or
783     * <code>null</code> if it is unconnected.
784     * <p>
785     * If the socket was connected prior to being {@link #close closed},
786     * then this method will continue to return the connected address
787     * after the socket is closed.
788     *
789
790     * @return a <code>SocketAddress</code> representing the remote endpoint of this
791     *         socket, or <code>null</code> if it is not connected yet.
792     * @see #getInetAddress()
793     * @see #getPort()
794     * @see #connect(SocketAddress, int)
795     * @see #connect(SocketAddress)
796     * @since 1.4
797     */
798    public SocketAddress getRemoteSocketAddress() {
799        if (!isConnected())
800            return null;
801        return new InetSocketAddress(getInetAddress(), getPort());
802    }
803
804    /**
805     * Returns the address of the endpoint this socket is bound to, or
806     * <code>null</code> if it is not bound yet.
807     * <p>
808     * If a socket bound to an endpoint represented by an
809     * <code>InetSocketAddress </code> is {@link #close closed},
810     * then this method will continue to return an <code>InetSocketAddress</code>
811     * after the socket is closed. In that case the returned
812     * <code>InetSocketAddress</code>'s address is the
813     * {@link InetAddress#isAnyLocalAddress wildcard} address
814     * and its port is the local port that it was bound to.
815     *
816     * @return a <code>SocketAddress</code> representing the local endpoint of this
817     *         socket, or <code>null</code> if it is not bound yet.
818     * @see #getLocalAddress()
819     * @see #getLocalPort()
820     * @see #bind(SocketAddress)
821     * @since 1.4
822     */
823
824    public SocketAddress getLocalSocketAddress() {
825        if (!isBound())
826            return null;
827        return new InetSocketAddress(getLocalAddress(), getLocalPort());
828    }
829
830    /**
831     * Returns the unique {@link java.nio.channels.SocketChannel SocketChannel}
832     * object associated with this socket, if any.
833     *
834     * <p> A socket will have a channel if, and only if, the channel itself was
835     * created via the {@link java.nio.channels.SocketChannel#open
836     * SocketChannel.open} or {@link
837     * java.nio.channels.ServerSocketChannel#accept ServerSocketChannel.accept}
838     * methods.
839     *
840     * @return  the socket channel associated with this socket,
841     *          or <tt>null</tt> if this socket was not created
842     *          for a channel
843     *
844     * @since 1.4
845     * @spec JSR-51
846     */
847    public SocketChannel getChannel() {
848        return null;
849    }
850
851    /**
852     * Returns an input stream for this socket.
853     *
854     * <p> If this socket has an associated channel then the resulting input
855     * stream delegates all of its operations to the channel.  If the channel
856     * is in non-blocking mode then the input stream's <tt>read</tt> operations
857     * will throw an {@link java.nio.channels.IllegalBlockingModeException}.
858     *
859     * <p>Under abnormal conditions the underlying connection may be
860     * broken by the remote host or the network software (for example
861     * a connection reset in the case of TCP connections). When a
862     * broken connection is detected by the network software the
863     * following applies to the returned input stream :-
864     *
865     * <ul>
866     *
867     *   <li><p>The network software may discard bytes that are buffered
868     *   by the socket. Bytes that aren't discarded by the network
869     *   software can be read using {@link java.io.InputStream#read read}.
870     *
871     *   <li><p>If there are no bytes buffered on the socket, or all
872     *   buffered bytes have been consumed by
873     *   {@link java.io.InputStream#read read}, then all subsequent
874     *   calls to {@link java.io.InputStream#read read} will throw an
875     *   {@link java.io.IOException IOException}.
876     *
877     *   <li><p>If there are no bytes buffered on the socket, and the
878     *   socket has not been closed using {@link #close close}, then
879     *   {@link java.io.InputStream#available available} will
880     *   return <code>0</code>.
881     *
882     * </ul>
883     *
884     * <p> Closing the returned {@link java.io.InputStream InputStream}
885     * will close the associated socket.
886     *
887     * @return     an input stream for reading bytes from this socket.
888     * @exception  IOException  if an I/O error occurs when creating the
889     *             input stream, the socket is closed, the socket is
890     *             not connected, or the socket input has been shutdown
891     *             using {@link #shutdownInput()}
892     *
893     * @revised 1.4
894     * @spec JSR-51
895     */
896    public InputStream getInputStream() throws IOException {
897        if (isClosed())
898            throw new SocketException("Socket is closed");
899        if (!isConnected())
900            throw new SocketException("Socket is not connected");
901        if (isInputShutdown())
902            throw new SocketException("Socket input is shutdown");
903        final Socket s = this;
904        InputStream is = null;
905        try {
906            is = AccessController.doPrivileged(
907                new PrivilegedExceptionAction<InputStream>() {
908                    public InputStream run() throws IOException {
909                        return impl.getInputStream();
910                    }
911                });
912        } catch (java.security.PrivilegedActionException e) {
913            throw (IOException) e.getException();
914        }
915        return is;
916    }
917
918    /**
919     * Returns an output stream for this socket.
920     *
921     * <p> If this socket has an associated channel then the resulting output
922     * stream delegates all of its operations to the channel.  If the channel
923     * is in non-blocking mode then the output stream's <tt>write</tt>
924     * operations will throw an {@link
925     * java.nio.channels.IllegalBlockingModeException}.
926     *
927     * <p> Closing the returned {@link java.io.OutputStream OutputStream}
928     * will close the associated socket.
929     *
930     * @return     an output stream for writing bytes to this socket.
931     * @exception  IOException  if an I/O error occurs when creating the
932     *               output stream or if the socket is not connected.
933     * @revised 1.4
934     * @spec JSR-51
935     */
936    public OutputStream getOutputStream() throws IOException {
937        if (isClosed())
938            throw new SocketException("Socket is closed");
939        if (!isConnected())
940            throw new SocketException("Socket is not connected");
941        if (isOutputShutdown())
942            throw new SocketException("Socket output is shutdown");
943        final Socket s = this;
944        OutputStream os = null;
945        try {
946            os = AccessController.doPrivileged(
947                new PrivilegedExceptionAction<OutputStream>() {
948                    public OutputStream run() throws IOException {
949                        return impl.getOutputStream();
950                    }
951                });
952        } catch (java.security.PrivilegedActionException e) {
953            throw (IOException) e.getException();
954        }
955        return os;
956    }
957
958    /**
959     * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
960     *
961     * @param on <code>true</code> to enable TCP_NODELAY,
962     * <code>false</code> to disable.
963     *
964     * @exception SocketException if there is an error
965     * in the underlying protocol, such as a TCP error.
966     *
967     * @since   JDK1.1
968     *
969     * @see #getTcpNoDelay()
970     */
971    public void setTcpNoDelay(boolean on) throws SocketException {
972        if (isClosed())
973            throw new SocketException("Socket is closed");
974        getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
975    }
976
977    /**
978     * Tests if TCP_NODELAY is enabled.
979     *
980     * @return a <code>boolean</code> indicating whether or not TCP_NODELAY is enabled.
981     * @exception SocketException if there is an error
982     * in the underlying protocol, such as a TCP error.
983     * @since   JDK1.1
984     * @see #setTcpNoDelay(boolean)
985     */
986    public boolean getTcpNoDelay() throws SocketException {
987        if (isClosed())
988            throw new SocketException("Socket is closed");
989        return ((Boolean) getImpl().getOption(SocketOptions.TCP_NODELAY)).booleanValue();
990    }
991
992    /**
993     * Enable/disable SO_LINGER with the specified linger time in seconds.
994     * The maximum timeout value is platform specific.
995     *
996     * The setting only affects socket close.
997     *
998     * @param on     whether or not to linger on.
999     * @param linger how long to linger for, if on is true.
1000     * @exception SocketException if there is an error
1001     * in the underlying protocol, such as a TCP error.
1002     * @exception IllegalArgumentException if the linger value is negative.
1003     * @since JDK1.1
1004     * @see #getSoLinger()
1005     */
1006    public void setSoLinger(boolean on, int linger) throws SocketException {
1007        if (isClosed())
1008            throw new SocketException("Socket is closed");
1009        if (!on) {
1010            getImpl().setOption(SocketOptions.SO_LINGER, new Boolean(on));
1011        } else {
1012            if (linger < 0) {
1013                throw new IllegalArgumentException("invalid value for SO_LINGER");
1014            }
1015            if (linger > 65535)
1016                linger = 65535;
1017            getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
1018        }
1019    }
1020
1021    /**
1022     * Returns setting for SO_LINGER. -1 returns implies that the
1023     * option is disabled.
1024     *
1025     * The setting only affects socket close.
1026     *
1027     * @return the setting for SO_LINGER.
1028     * @exception SocketException if there is an error
1029     * in the underlying protocol, such as a TCP error.
1030     * @since   JDK1.1
1031     * @see #setSoLinger(boolean, int)
1032     */
1033    public int getSoLinger() throws SocketException {
1034        if (isClosed())
1035            throw new SocketException("Socket is closed");
1036        Object o = getImpl().getOption(SocketOptions.SO_LINGER);
1037        if (o instanceof Integer) {
1038            return ((Integer) o).intValue();
1039        } else {
1040            return -1;
1041        }
1042    }
1043
1044    /**
1045     * Send one byte of urgent data on the socket. The byte to be sent is the lowest eight
1046     * bits of the data parameter. The urgent byte is
1047     * sent after any preceding writes to the socket OutputStream
1048     * and before any future writes to the OutputStream.
1049     * @param data The byte of data to send
1050     * @exception IOException if there is an error
1051     *  sending the data.
1052     * @since 1.4
1053     */
1054    public void sendUrgentData (int data) throws IOException  {
1055        if (!getImpl().supportsUrgentData ()) {
1056            throw new SocketException ("Urgent data not supported");
1057        }
1058        getImpl().sendUrgentData (data);
1059    }
1060
1061    /**
1062     * Enable/disable OOBINLINE (receipt of TCP urgent data)
1063     *
1064     * By default, this option is disabled and TCP urgent data received on a
1065     * socket is silently discarded. If the user wishes to receive urgent data, then
1066     * this option must be enabled. When enabled, urgent data is received
1067     * inline with normal data.
1068     * <p>
1069     * Note, only limited support is provided for handling incoming urgent
1070     * data. In particular, no notification of incoming urgent data is provided
1071     * and there is no capability to distinguish between normal data and urgent
1072     * data unless provided by a higher level protocol.
1073     *
1074     * @param on <code>true</code> to enable OOBINLINE,
1075     * <code>false</code> to disable.
1076     *
1077     * @exception SocketException if there is an error
1078     * in the underlying protocol, such as a TCP error.
1079     *
1080     * @since   1.4
1081     *
1082     * @see #getOOBInline()
1083     */
1084    public void setOOBInline(boolean on) throws SocketException {
1085        if (isClosed())
1086            throw new SocketException("Socket is closed");
1087        getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
1088    }
1089
1090    /**
1091     * Tests if OOBINLINE is enabled.
1092     *
1093     * @return a <code>boolean</code> indicating whether or not OOBINLINE is enabled.
1094     * @exception SocketException if there is an error
1095     * in the underlying protocol, such as a TCP error.
1096     * @since   1.4
1097     * @see #setOOBInline(boolean)
1098     */
1099    public boolean getOOBInline() throws SocketException {
1100        if (isClosed())
1101            throw new SocketException("Socket is closed");
1102        return ((Boolean) getImpl().getOption(SocketOptions.SO_OOBINLINE)).booleanValue();
1103    }
1104
1105    /**
1106     *  Enable/disable SO_TIMEOUT with the specified timeout, in
1107     *  milliseconds.  With this option set to a non-zero timeout,
1108     *  a read() call on the InputStream associated with this Socket
1109     *  will block for only this amount of time.  If the timeout expires,
1110     *  a <B>java.net.SocketTimeoutException</B> is raised, though the
1111     *  Socket is still valid. The option <B>must</B> be enabled
1112     *  prior to entering the blocking operation to have effect. The
1113     *  timeout must be > 0.
1114     *  A timeout of zero is interpreted as an infinite timeout.
1115     * @param timeout the specified timeout, in milliseconds.
1116     * @exception SocketException if there is an error
1117     * in the underlying protocol, such as a TCP error.
1118     * @since   JDK 1.1
1119     * @see #getSoTimeout()
1120     */
1121    public synchronized void setSoTimeout(int timeout) throws SocketException {
1122        if (isClosed())
1123            throw new SocketException("Socket is closed");
1124        if (timeout < 0)
1125          throw new IllegalArgumentException("timeout can't be negative");
1126
1127        getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
1128    }
1129
1130    /**
1131     * Returns setting for SO_TIMEOUT.  0 returns implies that the
1132     * option is disabled (i.e., timeout of infinity).
1133     * @return the setting for SO_TIMEOUT
1134     * @exception SocketException if there is an error
1135     * in the underlying protocol, such as a TCP error.
1136     * @since   JDK1.1
1137     * @see #setSoTimeout(int)
1138     */
1139    public synchronized int getSoTimeout() throws SocketException {
1140        if (isClosed())
1141            throw new SocketException("Socket is closed");
1142        Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
1143        /* extra type safety */
1144        if (o instanceof Integer) {
1145            return ((Integer) o).intValue();
1146        } else {
1147            return 0;
1148        }
1149    }
1150
1151    /**
1152     * Sets the SO_SNDBUF option to the specified value for this
1153     * <tt>Socket</tt>. The SO_SNDBUF option is used by the platform's
1154     * networking code as a hint for the size to set
1155     * the underlying network I/O buffers.
1156     *
1157     * <p>Because SO_SNDBUF is a hint, applications that want to
1158     * verify what size the buffers were set to should call
1159     * {@link #getSendBufferSize()}.
1160     *
1161     * @exception SocketException if there is an error
1162     * in the underlying protocol, such as a TCP error.
1163     *
1164     * @param size the size to which to set the send buffer
1165     * size. This value must be greater than 0.
1166     *
1167     * @exception IllegalArgumentException if the
1168     * value is 0 or is negative.
1169     *
1170     * @see #getSendBufferSize()
1171     * @since 1.2
1172     */
1173    public synchronized void setSendBufferSize(int size)
1174    throws SocketException{
1175        if (!(size > 0)) {
1176            throw new IllegalArgumentException("negative send size");
1177        }
1178        if (isClosed())
1179            throw new SocketException("Socket is closed");
1180        getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
1181    }
1182
1183    /**
1184     * Get value of the SO_SNDBUF option for this <tt>Socket</tt>,
1185     * that is the buffer size used by the platform
1186     * for output on this <tt>Socket</tt>.
1187     * @return the value of the SO_SNDBUF option for this <tt>Socket</tt>.
1188     *
1189     * @exception SocketException if there is an error
1190     * in the underlying protocol, such as a TCP error.
1191     *
1192     * @see #setSendBufferSize(int)
1193     * @since 1.2
1194     */
1195    public synchronized int getSendBufferSize() throws SocketException {
1196        if (isClosed())
1197            throw new SocketException("Socket is closed");
1198        int result = 0;
1199        Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
1200        if (o instanceof Integer) {
1201            result = ((Integer)o).intValue();
1202        }
1203        return result;
1204    }
1205
1206    /**
1207     * Sets the SO_RCVBUF option to the specified value for this
1208     * <tt>Socket</tt>. The SO_RCVBUF option is used by the platform's
1209     * networking code as a hint for the size to set
1210     * the underlying network I/O buffers.
1211     *
1212     * <p>Increasing the receive buffer size can increase the performance of
1213     * network I/O for high-volume connection, while decreasing it can
1214     * help reduce the backlog of incoming data.
1215     *
1216     * <p>Because SO_RCVBUF is a hint, applications that want to
1217     * verify what size the buffers were set to should call
1218     * {@link #getReceiveBufferSize()}.
1219     *
1220     * <p>The value of SO_RCVBUF is also used to set the TCP receive window
1221     * that is advertized to the remote peer. Generally, the window size
1222     * can be modified at any time when a socket is connected. However, if
1223     * a receive window larger than 64K is required then this must be requested
1224     * <B>before</B> the socket is connected to the remote peer. There are two
1225     * cases to be aware of:<p>
1226     * <ol>
1227     * <li>For sockets accepted from a ServerSocket, this must be done by calling
1228     * {@link ServerSocket#setReceiveBufferSize(int)} before the ServerSocket
1229     * is bound to a local address.<p></li>
1230     * <li>For client sockets, setReceiveBufferSize() must be called before
1231     * connecting the socket to its remote peer.<p></li></ol>
1232     * @param size the size to which to set the receive buffer
1233     * size. This value must be greater than 0.
1234     *
1235     * @exception IllegalArgumentException if the value is 0 or is
1236     * negative.
1237     *
1238     * @exception SocketException if there is an error
1239     * in the underlying protocol, such as a TCP error.
1240     *
1241     * @see #getReceiveBufferSize()
1242     * @see ServerSocket#setReceiveBufferSize(int)
1243     * @since 1.2
1244     */
1245    public synchronized void setReceiveBufferSize(int size)
1246    throws SocketException{
1247        if (size <= 0) {
1248            throw new IllegalArgumentException("invalid receive size");
1249        }
1250        if (isClosed())
1251            throw new SocketException("Socket is closed");
1252        getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
1253    }
1254
1255    /**
1256     * Gets the value of the SO_RCVBUF option for this <tt>Socket</tt>,
1257     * that is the buffer size used by the platform for
1258     * input on this <tt>Socket</tt>.
1259     *
1260     * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
1261     * @exception SocketException if there is an error
1262     * in the underlying protocol, such as a TCP error.
1263     * @see #setReceiveBufferSize(int)
1264     * @since 1.2
1265     */
1266    public synchronized int getReceiveBufferSize()
1267    throws SocketException{
1268        if (isClosed())
1269            throw new SocketException("Socket is closed");
1270        int result = 0;
1271        Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
1272        if (o instanceof Integer) {
1273            result = ((Integer)o).intValue();
1274        }
1275        return result;
1276    }
1277
1278    /**
1279     * Enable/disable SO_KEEPALIVE.
1280     *
1281     * @param on     whether or not to have socket keep alive turned on.
1282     * @exception SocketException if there is an error
1283     * in the underlying protocol, such as a TCP error.
1284     * @since 1.3
1285     * @see #getKeepAlive()
1286     */
1287    public void setKeepAlive(boolean on) throws SocketException {
1288        if (isClosed())
1289            throw new SocketException("Socket is closed");
1290        getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
1291    }
1292
1293    /**
1294     * Tests if SO_KEEPALIVE is enabled.
1295     *
1296     * @return a <code>boolean</code> indicating whether or not SO_KEEPALIVE is enabled.
1297     * @exception SocketException if there is an error
1298     * in the underlying protocol, such as a TCP error.
1299     * @since   1.3
1300     * @see #setKeepAlive(boolean)
1301     */
1302    public boolean getKeepAlive() throws SocketException {
1303        if (isClosed())
1304            throw new SocketException("Socket is closed");
1305        return ((Boolean) getImpl().getOption(SocketOptions.SO_KEEPALIVE)).booleanValue();
1306    }
1307
1308    /**
1309     * Sets traffic class or type-of-service octet in the IP
1310     * header for packets sent from this Socket.
1311     * As the underlying network implementation may ignore this
1312     * value applications should consider it a hint.
1313     *
1314     * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
1315     * 255</code> or an IllegalArgumentException will be thrown.
1316     * <p>Notes:
1317     * <p>For Internet Protocol v4 the value consists of an
1318     * <code>integer</code>, the least significant 8 bits of which
1319     * represent the value of the TOS octet in IP packets sent by
1320     * the socket.
1321     * RFC 1349 defines the TOS values as follows:
1322     * <p>
1323     * <UL>
1324     * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1325     * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1326     * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1327     * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1328     * </UL>
1329     * The last low order bit is always ignored as this
1330     * corresponds to the MBZ (must be zero) bit.
1331     * <p>
1332     * Setting bits in the precedence field may result in a
1333     * SocketException indicating that the operation is not
1334     * permitted.
1335     * <p>
1336     * As RFC 1122 section 4.2.4.2 indicates, a compliant TCP
1337     * implementation should, but is not required to, let application
1338     * change the TOS field during the lifetime of a connection.
1339     * So whether the type-of-service field can be changed after the
1340     * TCP connection has been established depends on the implementation
1341     * in the underlying platform. Applications should not assume that
1342     * they can change the TOS field after the connection.
1343     * <p>
1344     * For Internet Protocol v6 <code>tc</code> is the value that
1345     * would be placed into the sin6_flowinfo field of the IP header.
1346     *
1347     * @param tc        an <code>int</code> value for the bitset.
1348     * @throws SocketException if there is an error setting the
1349     * traffic class or type-of-service
1350     * @since 1.4
1351     * @see #getTrafficClass
1352     */
1353    public void setTrafficClass(int tc) throws SocketException {
1354        if (tc < 0 || tc > 255)
1355            throw new IllegalArgumentException("tc is not in range 0 -- 255");
1356
1357        if (isClosed())
1358            throw new SocketException("Socket is closed");
1359        getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
1360    }
1361
1362    /**
1363     * Gets traffic class or type-of-service in the IP header
1364     * for packets sent from this Socket
1365     * <p>
1366     * As the underlying network implementation may ignore the
1367     * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1368     * this method may return a different value than was previously
1369     * set using the {@link #setTrafficClass(int)} method on this Socket.
1370     *
1371     * @return the traffic class or type-of-service already set
1372     * @throws SocketException if there is an error obtaining the
1373     * traffic class or type-of-service value.
1374     * @since 1.4
1375     * @see #setTrafficClass(int)
1376     */
1377    public int getTrafficClass() throws SocketException {
1378        return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS))).intValue();
1379    }
1380
1381    /**
1382     * Enable/disable the SO_REUSEADDR socket option.
1383     * <p>
1384     * When a TCP connection is closed the connection may remain
1385     * in a timeout state for a period of time after the connection
1386     * is closed (typically known as the <tt>TIME_WAIT</tt> state
1387     * or <tt>2MSL</tt> wait state).
1388     * For applications using a well known socket address or port
1389     * it may not be possible to bind a socket to the required
1390     * <tt>SocketAddress</tt> if there is a connection in the
1391     * timeout state involving the socket address or port.
1392     * <p>
1393     * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
1394     * using {@link #bind(SocketAddress)} allows the socket to be
1395     * bound even though a previous connection is in a timeout
1396     * state.
1397     * <p>
1398     * When a <tt>Socket</tt> is created the initial setting
1399     * of <tt>SO_REUSEADDR</tt> is disabled.
1400     * <p>
1401     * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
1402     * disabled after a socket is bound (See {@link #isBound()})
1403     * is not defined.
1404     *
1405     * @param on  whether to enable or disable the socket option
1406     * @exception SocketException if an error occurs enabling or
1407     *            disabling the <tt>SO_RESUEADDR</tt> socket option,
1408     *            or the socket is closed.
1409     * @since 1.4
1410     * @see #getReuseAddress()
1411     * @see #bind(SocketAddress)
1412     * @see #isClosed()
1413     * @see #isBound()
1414     */
1415    public void setReuseAddress(boolean on) throws SocketException {
1416        if (isClosed())
1417            throw new SocketException("Socket is closed");
1418        getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
1419    }
1420
1421    /**
1422     * Tests if SO_REUSEADDR is enabled.
1423     *
1424     * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
1425     * @exception SocketException if there is an error
1426     * in the underlying protocol, such as a TCP error.
1427     * @since   1.4
1428     * @see #setReuseAddress(boolean)
1429     */
1430    public boolean getReuseAddress() throws SocketException {
1431        if (isClosed())
1432            throw new SocketException("Socket is closed");
1433        return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
1434    }
1435
1436    /**
1437     * Closes this socket.
1438     * <p>
1439     * Any thread currently blocked in an I/O operation upon this socket
1440     * will throw a {@link SocketException}.
1441     * <p>
1442     * Once a socket has been closed, it is not available for further networking
1443     * use (i.e. can't be reconnected or rebound). A new socket needs to be
1444     * created.
1445     *
1446     * <p> Closing this socket will also close the socket's
1447     * {@link java.io.InputStream InputStream} and
1448     * {@link java.io.OutputStream OutputStream}.
1449     *
1450     * <p> If this socket has an associated channel then the channel is closed
1451     * as well.
1452     *
1453     * @exception  IOException  if an I/O error occurs when closing this socket.
1454     * @revised 1.4
1455     * @spec JSR-51
1456     * @see #isClosed
1457     */
1458    public synchronized void close() throws IOException {
1459        synchronized(closeLock) {
1460            if (isClosed())
1461                return;
1462            if (created)
1463                impl.close();
1464            closed = true;
1465        }
1466    }
1467
1468    /**
1469     * Places the input stream for this socket at "end of stream".
1470     * Any data sent to the input stream side of the socket is acknowledged
1471     * and then silently discarded.
1472     * <p>
1473     * If you read from a socket input stream after invoking
1474     * shutdownInput() on the socket, the stream will return EOF.
1475     *
1476     * @exception IOException if an I/O error occurs when shutting down this
1477     * socket.
1478     *
1479     * @since 1.3
1480     * @see java.net.Socket#shutdownOutput()
1481     * @see java.net.Socket#close()
1482     * @see java.net.Socket#setSoLinger(boolean, int)
1483     * @see #isInputShutdown
1484     */
1485    public void shutdownInput() throws IOException
1486    {
1487        if (isClosed())
1488            throw new SocketException("Socket is closed");
1489        if (!isConnected())
1490            throw new SocketException("Socket is not connected");
1491        if (isInputShutdown())
1492            throw new SocketException("Socket input is already shutdown");
1493        getImpl().shutdownInput();
1494        shutIn = true;
1495    }
1496
1497    /**
1498     * Disables the output stream for this socket.
1499     * For a TCP socket, any previously written data will be sent
1500     * followed by TCP's normal connection termination sequence.
1501     *
1502     * If you write to a socket output stream after invoking
1503     * shutdownOutput() on the socket, the stream will throw
1504     * an IOException.
1505     *
1506     * @exception IOException if an I/O error occurs when shutting down this
1507     * socket.
1508     *
1509     * @since 1.3
1510     * @see java.net.Socket#shutdownInput()
1511     * @see java.net.Socket#close()
1512     * @see java.net.Socket#setSoLinger(boolean, int)
1513     * @see #isOutputShutdown
1514     */
1515    public void shutdownOutput() throws IOException
1516    {
1517        if (isClosed())
1518            throw new SocketException("Socket is closed");
1519        if (!isConnected())
1520            throw new SocketException("Socket is not connected");
1521        if (isOutputShutdown())
1522            throw new SocketException("Socket output is already shutdown");
1523        getImpl().shutdownOutput();
1524        shutOut = true;
1525    }
1526
1527    /**
1528     * Converts this socket to a <code>String</code>.
1529     *
1530     * @return  a string representation of this socket.
1531     */
1532    public String toString() {
1533        try {
1534            // Android changed : change localport to localPort, and addr to address.
1535            if (isConnected())
1536                return "Socket[address=" + getImpl().getInetAddress() +
1537                    ",port=" + getImpl().getPort() +
1538                    ",localPort=" + getImpl().getLocalPort() + "]";
1539        } catch (SocketException e) {
1540        }
1541        return "Socket[unconnected]";
1542    }
1543
1544    /**
1545     * Returns the connection state of the socket.
1546     * <p>
1547     * Note: Closing a socket doesn't clear its connection state, which means
1548     * this method will return <code>true</code> for a closed socket
1549     * (see {@link #isClosed()}) if it was successfuly connected prior
1550     * to being closed.
1551     *
1552     * @return true if the socket was successfuly connected to a server
1553     * @since 1.4
1554     */
1555    public boolean isConnected() {
1556        // Before 1.3 Sockets were always connected during creation
1557        return connected || oldImpl;
1558    }
1559
1560    /**
1561     * Returns the binding state of the socket.
1562     * <p>
1563     * Note: Closing a socket doesn't clear its binding state, which means
1564     * this method will return <code>true</code> for a closed socket
1565     * (see {@link #isClosed()}) if it was successfuly bound prior
1566     * to being closed.
1567     *
1568     * @return true if the socket was successfuly bound to an address
1569     * @since 1.4
1570     * @see #bind
1571     */
1572    public boolean isBound() {
1573        // Before 1.3 Sockets were always bound during creation
1574        return bound || oldImpl;
1575    }
1576
1577    /**
1578     * Returns the closed state of the socket.
1579     *
1580     * @return true if the socket has been closed
1581     * @since 1.4
1582     * @see #close
1583     */
1584    public boolean isClosed() {
1585        synchronized(closeLock) {
1586            return closed;
1587        }
1588    }
1589
1590    /**
1591     * Returns whether the read-half of the socket connection is closed.
1592     *
1593     * @return true if the input of the socket has been shutdown
1594     * @since 1.4
1595     * @see #shutdownInput
1596     */
1597    public boolean isInputShutdown() {
1598        return shutIn;
1599    }
1600
1601    /**
1602     * Returns whether the write-half of the socket connection is closed.
1603     *
1604     * @return true if the output of the socket has been shutdown
1605     * @since 1.4
1606     * @see #shutdownOutput
1607     */
1608    public boolean isOutputShutdown() {
1609        return shutOut;
1610    }
1611
1612    /**
1613     * The factory for all client sockets.
1614     */
1615    private static SocketImplFactory factory = null;
1616
1617    /**
1618     * Sets the client socket implementation factory for the
1619     * application. The factory can be specified only once.
1620     * <p>
1621     * When an application creates a new client socket, the socket
1622     * implementation factory's <code>createSocketImpl</code> method is
1623     * called to create the actual socket implementation.
1624     * <p>
1625     * Passing <code>null</code> to the method is a no-op unless the factory
1626     * was already set.
1627     * <p>If there is a security manager, this method first calls
1628     * the security manager's <code>checkSetFactory</code> method
1629     * to ensure the operation is allowed.
1630     * This could result in a SecurityException.
1631     *
1632     * @param      fac   the desired factory.
1633     * @exception  IOException  if an I/O error occurs when setting the
1634     *               socket factory.
1635     * @exception  SocketException  if the factory is already defined.
1636     * @exception  SecurityException  if a security manager exists and its
1637     *             <code>checkSetFactory</code> method doesn't allow the operation.
1638     * @see        java.net.SocketImplFactory#createSocketImpl()
1639     * @see        SecurityManager#checkSetFactory
1640     */
1641    public static synchronized void setSocketImplFactory(SocketImplFactory fac)
1642        throws IOException
1643    {
1644        if (factory != null) {
1645            throw new SocketException("factory already defined");
1646        }
1647        SecurityManager security = System.getSecurityManager();
1648        if (security != null) {
1649            security.checkSetFactory();
1650        }
1651        factory = fac;
1652    }
1653
1654    /**
1655     * Sets performance preferences for this socket.
1656     *
1657     * <p> Sockets use the TCP/IP protocol by default.  Some implementations
1658     * may offer alternative protocols which have different performance
1659     * characteristics than TCP/IP.  This method allows the application to
1660     * express its own preferences as to how these tradeoffs should be made
1661     * when the implementation chooses from the available protocols.
1662     *
1663     * <p> Performance preferences are described by three integers
1664     * whose values indicate the relative importance of short connection time,
1665     * low latency, and high bandwidth.  The absolute values of the integers
1666     * are irrelevant; in order to choose a protocol the values are simply
1667     * compared, with larger values indicating stronger preferences. Negative
1668     * values represent a lower priority than positive values. If the
1669     * application prefers short connection time over both low latency and high
1670     * bandwidth, for example, then it could invoke this method with the values
1671     * <tt>(1, 0, 0)</tt>.  If the application prefers high bandwidth above low
1672     * latency, and low latency above short connection time, then it could
1673     * invoke this method with the values <tt>(0, 1, 2)</tt>.
1674     *
1675     * <p> Invoking this method after this socket has been connected
1676     * will have no effect.
1677     *
1678     * @param  connectionTime
1679     *         An <tt>int</tt> expressing the relative importance of a short
1680     *         connection time
1681     *
1682     * @param  latency
1683     *         An <tt>int</tt> expressing the relative importance of low
1684     *         latency
1685     *
1686     * @param  bandwidth
1687     *         An <tt>int</tt> expressing the relative importance of high
1688     *         bandwidth
1689     *
1690     * @since 1.5
1691     */
1692    public void setPerformancePreferences(int connectionTime,
1693                                          int latency,
1694                                          int bandwidth)
1695    {
1696        /* Not implemented yet */
1697    }
1698
1699    /**
1700     * @hide internal use only
1701     */
1702    public FileDescriptor getFileDescriptor$() {
1703        return impl.getFileDescriptor();
1704    }
1705}
1706