151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project
38b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net;
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.DatagramChannel;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedExceptionAction;
34f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebskiimport android.system.ErrnoException;
35f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebskiimport libcore.io.Libcore;
36f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebskiimport static android.system.OsConstants.*;
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class represents a socket for sending and receiving datagram packets.
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>A datagram socket is the sending or receiving point for a packet
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * delivery service. Each packet sent or received on a datagram socket
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is individually addressed and routed. Multiple packets sent from
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * one machine to another may be routed differently, and may arrive in
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * any order.
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Where possible, a newly constructed {@code DatagramSocket} has the
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link SocketOptions#SO_BROADCAST SO_BROADCAST} socket option enabled so as
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to allow the transmission of broadcast datagrams. In order to receive
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * broadcast packets a DatagramSocket should be bound to the wildcard address.
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In some implementations, broadcast packets may also be received when
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a DatagramSocket is bound to a more specific address.
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Example:
553a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *              DatagramSocket s = new DatagramSocket(null);
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *              s.bind(new InetSocketAddress(8888));
583a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * }
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Which is equivalent to:
603a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *              DatagramSocket s = new DatagramSocket(8888);
623a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * }
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Both cases will create a DatagramSocket able to receive broadcasts on
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * UDP port 8888.
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author  Pavani Diwanji
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     java.net.DatagramPacket
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     java.nio.channels.DatagramChannel
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.0
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass DatagramSocket implements java.io.Closeable {
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Various states of this socket.
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean created = false;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean bound = false;
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean closed = false;
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Object closeLock = new Object();
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The implementation of this DatagramSocket.
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    DatagramSocketImpl impl;
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Are we using an older DatagramSocketImpl?
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean oldImpl = false;
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
916031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong    /**
926031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     * Set when a socket is ST_CONNECTED until we are certain
936031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     * that any packets which might have been received prior
946031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     * to calling connect() but not read by the application
956031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     * have been read. During this time we check the source
966031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     * address of all packets received to be sure they are from
976031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     * the connected destination. Other packets are read but
986031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     * silently dropped.
996031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong     */
1006031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong    private boolean explicitFilter = false;
1016031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong    private int bytesLeftToFilter;
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Connection state:
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ST_NOT_CONNECTED = socket not connected
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ST_CONNECTED = socket connected
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int ST_NOT_CONNECTED = 0;
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int ST_CONNECTED = 1;
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int ST_CONNECTED_NO_IMPL = 2;
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int connectState = ST_NOT_CONNECTED;
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Connected address & port
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    InetAddress connectedAddress = null;
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int connectedPort = -1;
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
1206975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer    // BEGIN Android-changed
1213ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak    private SocketException pendingConnectException;
1226975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer    // END Android-changed
1233ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Connects this socket to a remote socket address (IP address + port number).
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Binds socket if not already bound.
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
1283a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param   address The remote address.
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   port    The remote port
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  SocketException if binding the socket fails.
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private synchronized void connectInternal(InetAddress address, int port) throws SocketException {
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (port < 0 || port > 0xFFFF) {
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("connect: " + port);
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (address == null) {
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("connect: null address");
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress (address, "connect");
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (address.isMulticastAddress()) {
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                security.checkMulticast(address);
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                security.checkConnect(address.getHostAddress(), port);
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                security.checkAccept(address.getHostAddress(), port);
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!isBound())
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski          bind(new InetSocketAddress(0));
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
155979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller        // Android-changed: This section now throws any SocketException generated by connect()
156979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller        // to enable it to be recorded as the pendingConnectException. It has been enclosed in a
157979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller        // try-finally to ensure connectedAddress and connectedPort are set when the exception
158979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller        // is thrown.
159979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller        try {
160979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller            // old impls do not support connect/disconnect
161979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller            // Android-changed: Added special handling for AbstractPlainDatagramSocketImpl in
162979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller            // the condition below.
163979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller            if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl &&
164979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) {
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                connectState = ST_CONNECTED_NO_IMPL;
166979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller            } else {
167979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                try {
168979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    getImpl().connect(address, port);
169979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller
170979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    // socket is now connected by the impl
171979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    connectState = ST_CONNECTED;
172979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller
173979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    // Do we need to filter some packets?
174979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    int avail = getImpl().dataAvailable();
175979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    if (avail == -1) {
176979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                        throw new SocketException();
177979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    }
178979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    explicitFilter = avail > 0;
179979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    if (explicitFilter) {
180979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                        bytesLeftToFilter = getReceiveBufferSize();
181979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    }
182979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                } catch (SocketException se) {
183979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    // connection will be emulated by DatagramSocket
184979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    connectState = ST_CONNECTED_NO_IMPL;
185979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    // Android-changed: Propagate the SocketException so connect() can store it.
186979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                    throw se;
187979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller                }
188979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller           }
189979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller        } finally {
190979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller            connectedAddress = address;
191979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller            connectedPort = port;
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constructs a datagram socket and binds it to any available port
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on the local host machine.  The socket will be bound to the
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link InetAddress#isAnyLocalAddress wildcard} address,
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an IP address chosen by the kernel.
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
2033a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with 0 as its argument to ensure the operation is allowed.
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SocketException  if the socket could not be opened,
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *               or the socket could not bind to the specified local port.
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
2103a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public DatagramSocket() throws SocketException {
215dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong        this(new InetSocketAddress(0));
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates an unbound datagram socket with the specified
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DatagramSocketImpl.
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param impl an instance of a <B>DatagramSocketImpl</B>
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *        the subclass wishes to use on the DatagramSocket.
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   1.4
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected DatagramSocket(DatagramSocketImpl impl) {
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (impl == null)
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.impl = impl;
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkOldImpl();
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a datagram socket, bound to the specified local
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * socket address.
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
2373a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * If, if the address is {@code null}, creates an unbound socket.
2383a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
2403a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with the port from the socket address
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument to ensure the operation is allowed.
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
2453a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param bindaddr local socket address to bind, or {@code null}
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                 for an unbound socket.
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SocketException  if the socket could not be opened,
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *               or the socket could not bind to the specified local port.
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
2513a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   1.4
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public DatagramSocket(SocketAddress bindaddr) throws SocketException {
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // create a datagram socket.
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        createImpl();
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (bindaddr != null) {
260dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            try {
261dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                bind(bindaddr);
262dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            } finally {
263dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                if (!isBound())
264dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                    close();
265dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            }
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constructs a datagram socket and binds it to the specified port
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on the local host machine.  The socket will be bound to the
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link InetAddress#isAnyLocalAddress wildcard} address,
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an IP address chosen by the kernel.
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
2763a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
2773a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code port} argument
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument to ensure the operation is allowed.
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      port port to use.
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SocketException  if the socket could not be opened,
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *               or the socket could not bind to the specified local port.
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
2853a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public DatagramSocket(int port) throws SocketException {
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(port, null);
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a datagram socket, bound to the specified local
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * address.  The local port must be between 0 and 65535 inclusive.
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the IP address is 0.0.0.0, the socket will be bound to the
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link InetAddress#isAnyLocalAddress wildcard} address,
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an IP address chosen by the kernel.
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
3013a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
3023a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code port} argument
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument to ensure the operation is allowed.
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param port local port to use
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param laddr local address to bind
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SocketException  if the socket could not be opened,
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *               or the socket could not bind to the specified local port.
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
3123a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   JDK1.1
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public DatagramSocket(int port, InetAddress laddr) throws SocketException {
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(new InetSocketAddress(laddr, port));
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void checkOldImpl() {
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (impl == null)
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // getDeclaredMethod, therefore we need permission to access the member
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            AccessController.doPrivileged(
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                new PrivilegedExceptionAction<Void>() {
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    public Void run() throws NoSuchMethodException {
3303a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                        Class<?>[] cl = new Class<?>[1];
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        cl[0] = DatagramPacket.class;
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        impl.getClass().getDeclaredMethod("peekData", cl);
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return null;
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                });
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (java.security.PrivilegedActionException e) {
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            oldImpl = true;
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3413a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong    static Class<?> implClass = null;
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    void createImpl() throws SocketException {
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (impl == null) {
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (factory != null) {
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                impl = factory.createDatagramSocketImpl();
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                checkOldImpl();
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean isMulticast = (this instanceof MulticastSocket) ? true : false;
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(isMulticast);
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                checkOldImpl();
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // creates a udp socket
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        impl.create();
357e573e88e89daf5efb323719c54117c5a423eb245Yi Kong        impl.setDatagramSocket(this);
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        created = true;
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
3623a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Get the {@code DatagramSocketImpl} attached to this socket,
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * creating it if necessary.
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
3653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return  the {@code DatagramSocketImpl} attached to that
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          DatagramSocket
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SocketException if creation fails.
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    DatagramSocketImpl getImpl() throws SocketException {
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!created)
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            createImpl();
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return impl;
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
3773a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Binds this DatagramSocket to a specific address and port.
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
3793a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * If the address is {@code null}, then the system will pick up
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an ephemeral port and a valid local address to bind the socket.
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *<p>
3823a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param   addr The address and port to bind to.
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  SocketException if any error happens during the bind, or if the
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          socket is already bound.
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  SecurityException  if a security manager exists and its
3863a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IllegalArgumentException if addr is a SocketAddress subclass
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         not supported by this socket.
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void bind(SocketAddress addr) throws SocketException {
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isBound())
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("already bound");
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (addr == null)
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            addr = new InetSocketAddress(0);
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(addr instanceof InetSocketAddress))
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Unsupported address type!");
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        InetSocketAddress epoint = (InetSocketAddress) addr;
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (epoint.isUnresolved())
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Unresolved address");
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        InetAddress iaddr = epoint.getAddress();
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int port = epoint.getPort();
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(iaddr, "bind");
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager sec = System.getSecurityManager();
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sec != null) {
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sec.checkListen(port);
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().bind(port, iaddr);
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (SocketException e) {
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().close();
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw e;
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        bound = true;
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    void checkAddress (InetAddress addr, String op) {
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (addr == null) {
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException(op + ": invalid address type");
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Connects the socket to a remote address for this socket. When a
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * socket is connected to a remote address, packets may only be
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * sent to or received from that address. By default a datagram
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * socket is not connected.
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If the remote destination to which the socket is connected does not
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * exist, or is otherwise unreachable, and if an ICMP destination unreachable
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * packet has been received for that address, then a subsequent call to
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * send or receive may throw a PortUnreachableException. Note, there is no
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * guarantee that the exception will be thrown.
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> If a security manager has been installed then it is invoked to check
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * access to the remote address. Specifically, if the given {@code address}
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is a {@link InetAddress#isMulticastAddress multicast address},
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the security manager's {@link
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * java.lang.SecurityManager#checkMulticast(InetAddress)
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * checkMulticast} method is invoked with the given {@code address}.
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Otherwise, the security manager's {@link
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * are invoked, with the given {@code address} and {@code port}, to
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * verify that datagrams are permitted to be sent and received
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * respectively.
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> When a socket is connected, {@link #receive receive} and
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link #send send} <b>will not perform any security checks</b>
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on incoming and outgoing packets, other than matching the packet's
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and the socket's address and port. On a send operation, if the
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * packet's address is set and the packet's address and the socket's
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * address do not match, an {@code IllegalArgumentException} will be
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * thrown. A socket connected to a multicast address may only be used
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to send packets.
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param address the remote address for the socket
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param port the remote port for the socket.
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IllegalArgumentException
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         if the address is null, or the port is out of range.
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SecurityException
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         if a security manager has been installed and it does
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         not permit access to the given remote address
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #disconnect
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void connect(InetAddress address, int port) {
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            connectInternal(address, port);
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (SocketException se) {
4796975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer            // BEGIN Android-changed
4803ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak            //throw new Error("connect failed", se);
4813ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak            // TODO: or just use SneakyThrow? There's a clear API bug here.
482232065a74a6bfb1dcb7b31359108359932a3d737Przemyslaw Szczepaniak            pendingConnectException = se;
4836975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer            // END Android-changed
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Connects this socket to a remote socket address (IP address + port number).
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with the the given socket addresses IP address and port number.
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   addr    The remote address.
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  SocketException
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          if the connect fails
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IllegalArgumentException
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         subclass not supported by this socket
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SecurityException
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         if a security manager has been installed and it does
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         not permit access to the given remote address
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void connect(SocketAddress addr) throws SocketException {
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (addr == null)
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Address can't be null");
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(addr instanceof InetSocketAddress))
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Unsupported address type");
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        InetSocketAddress epoint = (InetSocketAddress) addr;
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (epoint.isUnresolved())
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Unresolved address");
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        connectInternal(epoint.getAddress(), epoint.getPort());
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Disconnects the socket. If the socket is closed or not connected,
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then this method has no effect.
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #connect
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void disconnect() {
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (this) {
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (isClosed())
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (connectState == ST_CONNECTED) {
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                impl.disconnect ();
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            connectedAddress = null;
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            connectedPort = -1;
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            connectState = ST_NOT_CONNECTED;
5366031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong            explicitFilter = false;
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the binding state of the socket.
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the socket was bound prior to being {@link #close closed},
5443a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * then this method will continue to return {@code true}
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * after the socket is closed.
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if the socket successfully bound to an address
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isBound() {
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return bound;
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the connection state of the socket.
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the socket was connected prior to being {@link #close closed},
5583a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * then this method will continue to return {@code true}
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * after the socket is closed.
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if the socket successfully connected to a server
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isConnected() {
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return connectState != ST_NOT_CONNECTED;
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the address to which this socket is connected. Returns
5703a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code null} if the socket is not connected.
57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the socket was connected prior to being {@link #close closed},
57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then this method will continue to return the connected address
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * after the socket is closed.
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the address to which this socket is connected.
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InetAddress getInetAddress() {
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return connectedAddress;
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the port number to which this socket is connected.
5843a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Returns {@code -1} if the socket is not connected.
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the socket was connected prior to being {@link #close closed},
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then this method will continue to return the connected port number
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * after the socket is closed.
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the port number to which this socket is connected.
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getPort() {
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return connectedPort;
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the address of the endpoint this socket is connected to, or
5983a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code null} if it is unconnected.
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the socket was connected prior to being {@link #close closed},
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then this method will continue to return the connected address
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * after the socket is closed.
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6043a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return a {@code SocketAddress} representing the remote
6053a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *         endpoint of this socket, or {@code null} if it is
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         not connected yet.
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getInetAddress()
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getPort()
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #connect(SocketAddress)
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketAddress getRemoteSocketAddress() {
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!isConnected())
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new InetSocketAddress(getInetAddress(), getPort());
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the address of the endpoint this socket is bound to.
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6213a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return a {@code SocketAddress} representing the local endpoint of this
6223a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *         socket, or {@code null} if it is closed or not bound yet.
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getLocalAddress()
62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getLocalPort()
62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #bind(SocketAddress)
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketAddress getLocalSocketAddress() {
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!isBound())
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new InetSocketAddress(getLocalAddress(), getLocalPort());
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sends a datagram packet from this socket. The
6393a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code DatagramPacket} includes information indicating the
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * data to be sent, its length, the IP address of the remote host,
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and the port number on the remote host.
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, and the socket is not currently
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * connected to a remote address, this method first performs some
6453a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * security checks. First, if {@code p.getAddress().isMulticastAddress()}
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is true, this method calls the
6473a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * security manager's {@code checkMulticast} method
6483a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with {@code p.getAddress()} as its argument.
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the evaluation of that expression is false,
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method instead calls the security manager's
6513a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkConnect} method with arguments
6523a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code p.getAddress().getHostAddress()} and
6533a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code p.getPort()}. Each call to a security manager method
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * could result in a SecurityException if the operation is not allowed.
65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6563a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param      p   the {@code DatagramPacket} to be sent.
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
6603a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkMulticast} or {@code checkConnect}
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             method doesn't allow the send.
66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  PortUnreachableException may be thrown if the socket is connected
66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             to a currently unreachable destination. Note, there is no
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             guarantee that the exception will be thrown.
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  java.nio.channels.IllegalBlockingModeException
66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             if this socket has an associated channel,
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             and the channel is in non-blocking mode.
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IllegalArgumentException if the socket is connected,
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             and connected address and packet address differ.
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        java.net.DatagramPacket
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        SecurityManager#checkMulticast(InetAddress)
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        SecurityManager#checkConnect
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @revised 1.4
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @spec JSR-51
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void send(DatagramPacket p) throws IOException  {
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        InetAddress packetAddress = null;
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (p) {
6806975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer            // BEGIN Android-changed
6813a50b32e2abec315948e1947450cd0f7c0c82b2dHans MÃ¥nsson            if (pendingConnectException != null) {
6823a50b32e2abec315948e1947450cd0f7c0c82b2dHans MÃ¥nsson                throw new SocketException("Pending connect failure", pendingConnectException);
6833a50b32e2abec315948e1947450cd0f7c0c82b2dHans MÃ¥nsson            }
6846975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer            // END Android-changed
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (isClosed())
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new SocketException("Socket is closed");
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            checkAddress (p.getAddress(), "send");
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (connectState == ST_NOT_CONNECTED) {
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // check the address is ok wiht the security manager on every send.
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                SecurityManager security = System.getSecurityManager();
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // The reason you want to synchronize on datagram packet
6933a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                // is because you don't want an applet to change the address
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // while you are trying to send the packet for example
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // after the security check but before the send.
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (security != null) {
69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (p.getAddress().isMulticastAddress()) {
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        security.checkMulticast(p.getAddress());
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        security.checkConnect(p.getAddress().getHostAddress(),
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                              p.getPort());
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // we're connected
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                packetAddress = p.getAddress();
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (packetAddress == null) {
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    p.setAddress(connectedAddress);
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    p.setPort(connectedPort);
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if ((!packetAddress.equals(connectedAddress)) ||
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                           p.getPort() != connectedPort) {
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new IllegalArgumentException("connected address " +
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                       "and packet address" +
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                       " differ");
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Check whether the socket is bound
71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isBound())
71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                bind(new InetSocketAddress(0));
72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // call the  method to send
72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().send(p);
72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Receives a datagram packet from this socket. When this method
7273a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * returns, the {@code DatagramPacket}'s buffer is filled with
72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the data received. The datagram packet also contains the sender's
72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * IP address, and the port number on the sender's machine.
73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This method blocks until a datagram is received. The
7323a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code length} field of the datagram packet object contains
73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the length of the received message. If the message is longer than
73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the packet's length, the message is truncated.
73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If there is a security manager, a packet cannot be received if the
7373a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * security manager's {@code checkAccept} method
73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * does not allow it.
73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
7403a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param      p   the {@code DatagramPacket} into which to place
74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                 the incoming data.
74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SocketTimeoutException  if setSoTimeout was previously called
74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                 and the timeout has expired.
74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  PortUnreachableException may be thrown if the socket is connected
74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             to a currently unreachable destination. Note, there is no guarantee that the
74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             exception will be thrown.
74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  java.nio.channels.IllegalBlockingModeException
74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             if this socket has an associated channel,
75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             and the channel is in non-blocking mode.
75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        java.net.DatagramPacket
75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        java.net.DatagramSocket
75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @revised 1.4
75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @spec JSR-51
75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void receive(DatagramPacket p) throws IOException {
75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (p) {
75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!isBound())
75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                bind(new InetSocketAddress(0));
7603ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak
7616975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer            // BEGIN Android-changed
7623ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak            if (pendingConnectException != null) {
7633ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak                throw new SocketException("Pending connect failure", pendingConnectException);
7643ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak            }
7656975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer            // END Android-changed
7663ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak
76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (connectState == ST_NOT_CONNECTED) {
76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // check the address is ok with the security manager before every recv.
76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                SecurityManager security = System.getSecurityManager();
77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (security != null) {
77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    while(true) {
77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        String peekAd = null;
77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int peekPort = 0;
77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // peek at the packet to see who it is from.
77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (!oldImpl) {
77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // We can use the new peekData() API
77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            peekPort = getImpl().peekData(peekPacket);
77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            peekAd = peekPacket.getAddress().getHostAddress();
78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else {
78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            InetAddress adr = new InetAddress();
78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            peekPort = getImpl().peek(adr);
78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            peekAd = adr.getHostAddress();
78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        try {
78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            security.checkAccept(peekAd, peekPort);
78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // security check succeeded - so now break
78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // and recv the packet.
78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            break;
79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } catch (SecurityException se) {
79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // Throw away the offending packet by consuming
79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // it in a tmp buffer.
79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            getImpl().receive(tmp);
79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // silently discard the offending packet
79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // and continue: unknown/malicious
79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // entities on nets should not make
79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // runtime throw security exception and
80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // disrupt the applet by sending random
80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // datagram packets.
80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            continue;
80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } // end of while
80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
8078b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong            DatagramPacket tmp = null;
8086031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong            if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) {
80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // We have to do the filtering the old fashioned way since
81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // the native impl doesn't support connect or the connect
8116031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong                // via the impl failed, or .. "explicitFilter" may be set when
8126031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong                // a socket is connected via the impl, for a period of time
8136031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong                // when packets from other sources might be queued on socket.
81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean stop = false;
81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while (!stop) {
81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    InetAddress peekAddress = null;
81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int peekPort = -1;
81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // peek at the packet to see who it is from.
81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!oldImpl) {
82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // We can use the new peekData() API
82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        peekPort = getImpl().peekData(peekPacket);
82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        peekAddress = peekPacket.getAddress();
82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // this api only works for IPv4
82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        peekAddress = new InetAddress();
82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        peekPort = getImpl().peek(peekAddress);
82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((!connectedAddress.equals(peekAddress)) ||
83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (connectedPort != peekPort)) {
83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // throw the packet away and silently continue
8328b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong                        tmp = new DatagramPacket(
8336031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong                                                new byte[1024], 1024);
83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        getImpl().receive(tmp);
8356031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong                        if (explicitFilter) {
8368b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong                            if (checkFiltering(tmp)) {
8378b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong                                stop = true;
8388b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong                            }
8396031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong                        }
84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        stop = true;
84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // If the security check succeeds, or the datagram is
84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // connected then receive the packet
84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().receive(p);
8488b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong            if (explicitFilter && tmp == null) {
8498b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong                // packet was not filtered, account for it here
8508b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong                checkFiltering(p);
8516031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong            }
85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8558b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong    private boolean checkFiltering(DatagramPacket p) throws SocketException {
8568b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong        bytesLeftToFilter -= p.getLength();
8578b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong        if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) {
8588b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong            explicitFilter = false;
8598b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong            return true;
8608b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong        }
8618b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong        return false;
8628b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong    }
8638b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong
86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Gets the local address to which the socket is bound.
86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, its
8683a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkConnect} method is first called
8693a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the host address and {@code -1}
87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its arguments to see if the operation is allowed.
87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkConnect
87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  the local address to which the socket is bound,
8743a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *          {@code null} if the socket is closed, or
8753a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *          an {@code InetAddress} representing
87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          {@link InetAddress#isAnyLocalAddress wildcard}
87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          address if either the socket is not bound, or
8783a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *          the security manager {@code checkConnect}
87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          method does not allow the operation
88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   1.1
88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InetAddress getLocalAddress() {
88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        InetAddress in = null;
88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (in.isAnyLocalAddress()) {
88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                in = InetAddress.anyLocalAddress();
89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            SecurityManager s = System.getSecurityManager();
89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (s != null) {
89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                s.checkConnect(in.getHostAddress(), -1);
89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception e) {
89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            in = InetAddress.anyLocalAddress(); // "0.0.0.0"
89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return in;
89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the port number on the local host to which this socket
90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is bound.
90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  the port number on the local host to which this socket is bound,
9063a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                {@code -1} if the socket is closed, or
9073a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                {@code 0} if it is not bound yet.
90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getLocalPort() {
91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return -1;
91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return getImpl().getLocalPort();
91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception e) {
91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /** Enable/disable SO_TIMEOUT with the specified timeout, in
92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  milliseconds. With this option set to a non-zero timeout,
92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  a call to receive() for this DatagramSocket
92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  will block for only this amount of time.  If the timeout expires,
92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  a <B>java.net.SocketTimeoutException</B> is raised, though the
92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  DatagramSocket is still valid.  The option <B>must</B> be enabled
92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  prior to entering the blocking operation to have effect.  The
9263a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *  timeout must be {@code > 0}.
92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  A timeout of zero is interpreted as an infinite timeout.
92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param timeout the specified timeout in milliseconds.
93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   JDK1.1
93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getSoTimeout()
93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void setSoTimeout(int timeout) throws SocketException {
93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * option is disabled (i.e., timeout of infinity).
94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the setting for SO_TIMEOUT
94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   JDK1.1
94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setSoTimeout(int)
94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized int getSoTimeout() throws SocketException {
95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (getImpl() == null)
95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /* extra type safety */
95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (o instanceof Integer) {
95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return ((Integer) o).intValue();
95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets the SO_SNDBUF option to the specified value for this
9653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code DatagramSocket}. The SO_SNDBUF option is used by the
96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * network implementation as a hint to size the underlying
96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * network I/O buffers. The SO_SNDBUF setting may also be used
96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by the network implementation to determine the maximum size
96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of the packet that can be sent on this socket.
97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * As SO_SNDBUF is a hint, applications that want to verify
97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * what size the buffer is should call {@link #getSendBufferSize()}.
97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Increasing the buffer size may allow multiple outgoing packets
97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to be queued by the network implementation when the send rate
97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is high.
97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note: If {@link #send(DatagramPacket)} is used to send a
9793a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code DatagramPacket} that is larger than the setting
98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of SO_SNDBUF then it is implementation specific if the
98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * packet is sent or discarded.
98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param size the size to which to set the send buffer
98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * size. This value must be greater than 0.
98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error
98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in the underlying protocol, such as an UDP error.
98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IllegalArgumentException if the value is 0 or is
98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * negative.
99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getSendBufferSize()
99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void setSendBufferSize(int size)
99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws SocketException{
99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(size > 0)) {
99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("negative send size");
99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
10033a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Get value of the SO_SNDBUF option for this {@code DatagramSocket}, that is the
10043a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * buffer size used by the platform for output on this {@code DatagramSocket}.
100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10063a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return the value of the SO_SNDBUF option for this {@code DatagramSocket}
100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as an UDP error.
100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setSendBufferSize
101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized int getSendBufferSize() throws SocketException {
101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int result = 0;
101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (o instanceof Integer) {
101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result = ((Integer)o).intValue();
101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result;
102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets the SO_RCVBUF option to the specified value for this
10243a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code DatagramSocket}. The SO_RCVBUF option is used by the
102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the network implementation as a hint to size the underlying
102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * network I/O buffers. The SO_RCVBUF setting may also be used
102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by the network implementation to determine the maximum size
102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of the packet that can be received on this socket.
102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Because SO_RCVBUF is a hint, applications that want to
103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * verify what size the buffers were set to should call
103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link #getReceiveBufferSize()}.
103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Increasing SO_RCVBUF may allow the network implementation
103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to buffer multiple packets when packets arrive faster than
103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * are being received using {@link #receive(DatagramPacket)}.
103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note: It is implementation specific if a packet larger
103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * than SO_RCVBUF can be received.
104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param size the size to which to set the receive buffer
104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * size. This value must be greater than 0.
104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as an UDP error.
104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IllegalArgumentException if the value is 0 or is
104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * negative.
104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getReceiveBufferSize()
104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void setReceiveBufferSize(int size)
105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws SocketException{
105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (size <= 0) {
105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("invalid receive size");
105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
10613a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Get value of the SO_RCVBUF option for this {@code DatagramSocket}, that is the
10623a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * buffer size used by the platform for input on this {@code DatagramSocket}.
106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10643a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return the value of the SO_RCVBUF option for this {@code DatagramSocket}
106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in the underlying protocol, such as an UDP error.
106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setReceiveBufferSize(int)
106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized int getReceiveBufferSize()
106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws SocketException{
107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int result = 0;
107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (o instanceof Integer) {
107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result = ((Integer)o).intValue();
107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result;
107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Enable/disable the SO_REUSEADDR socket option.
108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * For UDP sockets it may be necessary to bind more than one
108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * socket to the same socket address. This is typically for the
108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * purpose of receiving multicast packets
108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * (See {@link java.net.MulticastSocket}). The
10873a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code SO_REUSEADDR} socket option allows multiple
108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * sockets to be bound to the same socket address if the
10893a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code SO_REUSEADDR} socket option is enabled prior
109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to binding the socket using {@link #bind(SocketAddress)}.
109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note: This functionality is not supported by all existing platforms,
109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * so it is implementation specific whether this option will be ignored
109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or not. However, if it is not supported then
10953a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@link #getReuseAddress()} will always return {@code false}.
109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
10973a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * When a {@code DatagramSocket} is created the initial setting
10983a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * of {@code SO_REUSEADDR} is disabled.
109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
11003a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * The behaviour when {@code SO_REUSEADDR} is enabled or
110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * disabled after a socket is bound (See {@link #isBound()})
110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is not defined.
110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param on  whether to enable or disable the
110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if an error occurs enabling or
11063a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *            disabling the {@code SO_RESUEADDR} socket option,
110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *            or the socket is closed.
110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getReuseAddress()
111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #bind(SocketAddress)
111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #isBound()
111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #isClosed()
111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void setReuseAddress(boolean on) throws SocketException {
111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Integer instead of Boolean for compatibility with older DatagramSocketImpl
111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (oldImpl)
111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().setOption(SocketOptions.SO_REUSEADDR, new Integer(on?-1:0));
112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else
112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tests if SO_REUSEADDR is enabled.
112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
11273a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return a {@code boolean} indicating whether or not SO_REUSEADDR is enabled.
112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error
112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in the underlying protocol, such as an UDP error.
113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   1.4
113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setReuseAddress(boolean)
113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized boolean getReuseAddress() throws SocketException {
113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ((Boolean)o).booleanValue();
113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Enable/disable SO_BROADCAST.
114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Some operating systems may require that the Java virtual machine be
114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * started with implementation specific privileges to enable this option or
114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * send broadcast datagrams.
114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  on
114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         whether or not to have broadcast turned on.
114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  SocketException
115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          if there is an error in the underlying protocol, such as an UDP
115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          error.
115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getBroadcast()
115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void setBroadcast(boolean on) throws SocketException {
115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on));
116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tests if SO_BROADCAST is enabled.
11653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return a {@code boolean} indicating whether or not SO_BROADCAST is enabled.
116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error
116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in the underlying protocol, such as an UDP error.
116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setBroadcast(boolean)
117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized boolean getBroadcast() throws SocketException {
117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue();
117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets traffic class or type-of-service octet in the IP
117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * datagram header for datagrams sent from this DatagramSocket.
118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * As the underlying network implementation may ignore this
118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * value applications should consider it a hint.
118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
11833a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * <P> The tc <B>must</B> be in the range {@code 0 <= tc <=
11843a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * 255} or an IllegalArgumentException will be thrown.
118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>Notes:
118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>For Internet Protocol v4 the value consists of an
11873a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code integer}, the least significant 8 bits of which
118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * represent the value of the TOS octet in IP packets sent by
118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the socket.
119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC 1349 defines the TOS values as follows:
11913a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *
119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <UL>
119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * </UL>
119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The last low order bit is always ignored as this
119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * corresponds to the MBZ (must be zero) bit.
120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Setting bits in the precedence field may result in a
120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * SocketException indicating that the operation is not
120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * permitted.
120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
12053a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * for Internet Protocol v6 {@code tc} is the value that
120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * would be placed into the sin6_flowinfo field of the IP header.
120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
12083a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param tc        an {@code int} value for the bitset.
120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SocketException if there is an error setting the
121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * traffic class or type-of-service
121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getTrafficClass
121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized void setTrafficClass(int tc) throws SocketException {
121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (tc < 0 || tc > 255)
121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("tc is not in range 0 -- 255");
121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
1220780a0e6392567eb5d1c3425043b092d29590976bYi Kong        try {
1221780a0e6392567eb5d1c3425043b092d29590976bYi Kong            getImpl().setOption(SocketOptions.IP_TOS, tc);
1222780a0e6392567eb5d1c3425043b092d29590976bYi Kong        } catch (SocketException se) {
1223780a0e6392567eb5d1c3425043b092d29590976bYi Kong            // not supported if socket already connected
1224780a0e6392567eb5d1c3425043b092d29590976bYi Kong            // Solaris returns error in such cases
1225780a0e6392567eb5d1c3425043b092d29590976bYi Kong            if(!isConnected())
1226780a0e6392567eb5d1c3425043b092d29590976bYi Kong                throw se;
1227780a0e6392567eb5d1c3425043b092d29590976bYi Kong        }
122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Gets traffic class or type-of-service in the IP datagram
123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * header for packets sent from this DatagramSocket.
123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * As the underlying network implementation may ignore the
123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * traffic class or type-of-service set using {@link #setTrafficClass(int)}
123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method may return a different value than was previously
123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * set using the {@link #setTrafficClass(int)} method on this
123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DatagramSocket.
123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the traffic class or type-of-service already set
124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SocketException if there is an error obtaining the
124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * traffic class or type-of-service value.
124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setTrafficClass(int)
124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized int getTrafficClass() throws SocketException {
124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue();
125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Closes this datagram socket.
125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Any thread currently blocked in {@link #receive} upon this socket
125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * will throw a {@link SocketException}.
125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> If this socket has an associated channel then the channel is closed
125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as well.
126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @revised 1.4
126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @spec JSR-51
126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void close() {
126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized(closeLock) {
126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (isClosed())
126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            impl.close();
126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            closed = true;
127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns whether the socket is closed or not.
127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if the socket has been closed
127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isClosed() {
128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized(closeLock) {
128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return closed;
128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the unique {@link java.nio.channels.DatagramChannel} object
128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * associated with this datagram socket, if any.
128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> A datagram socket will have a channel if, and only if, the channel
129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * itself was created via the {@link java.nio.channels.DatagramChannel#open
129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DatagramChannel.open} method.
129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  the datagram channel associated with this datagram socket,
12943a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *          or {@code null} if this socket was not created for a channel
129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @spec JSR-51
129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public DatagramChannel getChannel() {
130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return null;
130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * User defined factory for all datagram sockets.
130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static DatagramSocketImplFactory factory;
130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets the datagram socket implementation factory for the
131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * application. The factory can be specified only once.
131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * When an application creates a new datagram socket, the socket
13133a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * implementation factory's {@code createDatagramSocketImpl} method is
131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * called to create the actual datagram socket implementation.
131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
13163a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Passing {@code null} to the method is a no-op unless the factory
131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * was already set.
131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first calls
13203a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * the security manager's {@code checkSetFactory} method
132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to ensure the operation is allowed.
132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      fac   the desired factory.
132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs when setting the
132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *              datagram socket factory.
132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SocketException  if the factory is already defined.
132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
13293a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkSetFactory} method doesn't allow the
133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     operation.
133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see
133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see       SecurityManager#checkSetFactory
133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.3
133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static synchronized void
133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       throws IOException
133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (factory != null) {
134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("factory already defined");
134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkSetFactory();
134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        factory = fac;
134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
1349f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski
135062098900d7201b01db7905a8ff1debea4b639a30Yi Kong    /**
135162098900d7201b01db7905a8ff1debea4b639a30Yi Kong     * Android-added: for testing and internal use.
135262098900d7201b01db7905a8ff1debea4b639a30Yi Kong     *
135362098900d7201b01db7905a8ff1debea4b639a30Yi Kong     * @hide internal use only
135462098900d7201b01db7905a8ff1debea4b639a30Yi Kong     */
1355e409de23a3281073142ff137b609778d6c70a31cYi Kong    public FileDescriptor getFileDescriptor$() {
1356f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski        return impl.fd;
1357f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski    }
1358f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski
1359f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski    /**
136062098900d7201b01db7905a8ff1debea4b639a30Yi Kong     * Android-added:
1361f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     * Sets the network interface used by this socket.  Any packets sent
1362f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     * via this socket are transmitted via the specified interface.  Any
1363f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     * packets received by this socket will come from the specified
1364f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     * interface.  Broadcast datagrams received on this interface will
1365f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     * be processed by this socket. This corresponds to Linux's SO_BINDTODEVICE.
1366f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     *
1367f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     * @hide used by GoogleTV for DHCP
1368f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski     */
1369f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski    public void setNetworkInterface(NetworkInterface netInterface) throws SocketException {
1370f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski        if (netInterface == null) {
1371f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski            throw new NullPointerException("netInterface == null");
1372f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski        }
1373f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski        try {
1374f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski            Libcore.os.setsockoptIfreq(impl.fd, SOL_SOCKET, SO_BINDTODEVICE, netInterface.getName());
1375f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski        } catch (ErrnoException errnoException) {
1376f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski            throw errnoException.rethrowAsSocketException();
1377f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski        }
1378f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski    }
137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
1380