1 /*
   2  * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.net;
  27 
  28 import java.io.FileDescriptor;
  29 import java.io.IOException;
  30 import java.io.InterruptedIOException;
  31 import java.nio.channels.DatagramChannel;
  32 import java.security.AccessController;
  33 import java.security.PrivilegedExceptionAction;
  34 
  35 /**
  36  * This class represents a socket for sending and receiving datagram packets.
  37  *
  38  * <p>A datagram socket is the sending or receiving point for a packet
  39  * delivery service. Each packet sent or received on a datagram socket
  40  * is individually addressed and routed. Multiple packets sent from
  41  * one machine to another may be routed differently, and may arrive in
  42  * any order.
  43  *
  44  * <p> Where possible, a newly constructed {@code DatagramSocket} has the
  45  * {@link SocketOptions#SO_BROADCAST SO_BROADCAST} socket option enabled so as
  46  * to allow the transmission of broadcast datagrams. In order to receive
  47  * broadcast packets a DatagramSocket should be bound to the wildcard address.
  48  * In some implementations, broadcast packets may also be received when
  49  * a DatagramSocket is bound to a more specific address.
  50  * <p>
  51  * Example:
  52  * <code>
  53  *              DatagramSocket s = new DatagramSocket(null);
  54  *              s.bind(new InetSocketAddress(8888));
  55  * </code>
  56  * Which is equivalent to:
  57  * <code>
  58  *              DatagramSocket s = new DatagramSocket(8888);
  59  * </code>
  60  * Both cases will create a DatagramSocket able to receive broadcasts on
  61  * UDP port 8888.
  62  *
  63  * @author  Pavani Diwanji
  64  * @see     java.net.DatagramPacket
  65  * @see     java.nio.channels.DatagramChannel
  66  * @since JDK1.0
  67  */
  68 public
  69 class DatagramSocket implements java.io.Closeable {
  70     /**
  71      * Various states of this socket.
  72      */
  73     private boolean created = false;
  74     private boolean bound = false;
  75     private boolean closed = false;
  76     private Object closeLock = new Object();
  77 
  78     /*
  79      * The implementation of this DatagramSocket.
  80      */
  81     DatagramSocketImpl impl;
  82 
  83     /**
  84      * Are we using an older DatagramSocketImpl?
  85      */
  86     boolean oldImpl = false;
  87 
  88     /*
  89      * Connection state:
  90      * ST_NOT_CONNECTED = socket not connected
  91      * ST_CONNECTED = socket connected
  92      * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
  93      */
  94     static final int ST_NOT_CONNECTED = 0;
  95     static final int ST_CONNECTED = 1;
  96     static final int ST_CONNECTED_NO_IMPL = 2;
  97 
  98     int connectState = ST_NOT_CONNECTED;
  99 
 100     /*
 101      * Connected address & port
 102      */
 103     InetAddress connectedAddress = null;
 104     int connectedPort = -1;
 105 
 106     /**
 107      * Connects this socket to a remote socket address (IP address + port number).
 108      * Binds socket if not already bound.
 109      * <p>
 110      * @param   addr    The remote address.
 111      * @param   port    The remote port
 112      * @throws  SocketException if binding the socket fails.
 113      */
 114     private synchronized void connectInternal(InetAddress address, int port) throws SocketException {
 115         if (port < 0 || port > 0xFFFF) {
 116             throw new IllegalArgumentException("connect: " + port);
 117         }
 118         if (address == null) {
 119             throw new IllegalArgumentException("connect: null address");
 120         }
 121         checkAddress (address, "connect");
 122         if (isClosed())
 123             return;
 124         SecurityManager security = System.getSecurityManager();
 125         if (security != null) {
 126             if (address.isMulticastAddress()) {
 127                 security.checkMulticast(address);
 128             } else {
 129                 security.checkConnect(address.getHostAddress(), port);
 130                 security.checkAccept(address.getHostAddress(), port);
 131             }
 132         }
 133 
 134         if (!isBound())
 135           bind(new InetSocketAddress(0));
 136 
 137         // old impls do not support connect/disconnect
 138         if (oldImpl) {
 139             connectState = ST_CONNECTED_NO_IMPL;
 140         } else {
 141             try {
 142                 getImpl().connect(address, port);
 143 
 144                 // socket is now connected by the impl
 145                 connectState = ST_CONNECTED;
 146             } catch (SocketException se) {
 147 
 148                 // connection will be emulated by DatagramSocket
 149                 connectState = ST_CONNECTED_NO_IMPL;
 150             }
 151         }
 152 
 153         connectedAddress = address;
 154         connectedPort = port;
 155     }
 156 
 157 
 158     /**
 159      * Constructs a datagram socket and binds it to any available port
 160      * on the local host machine.  The socket will be bound to the
 161      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 162      * an IP address chosen by the kernel.
 163      *
 164      * <p>If there is a security manager,
 165      * its <code>checkListen</code> method is first called
 166      * with 0 as its argument to ensure the operation is allowed.
 167      * This could result in a SecurityException.
 168      *
 169      * @exception  SocketException  if the socket could not be opened,
 170      *               or the socket could not bind to the specified local port.
 171      * @exception  SecurityException  if a security manager exists and its
 172      *             <code>checkListen</code> method doesn't allow the operation.
 173      *
 174      * @see SecurityManager#checkListen
 175      */
 176     public DatagramSocket() throws SocketException {
 177         // create a datagram socket.
 178         createImpl();
 179         try {
 180             bind(new InetSocketAddress(0));
 181         } catch (SocketException se) {
 182             throw se;
 183         } catch(IOException e) {
 184             throw new SocketException(e.getMessage());
 185         }
 186     }
 187 
 188     /**
 189      * Creates an unbound datagram socket with the specified
 190      * DatagramSocketImpl.
 191      *
 192      * @param impl an instance of a <B>DatagramSocketImpl</B>
 193      *        the subclass wishes to use on the DatagramSocket.
 194      * @since   1.4
 195      */
 196     protected DatagramSocket(DatagramSocketImpl impl) {
 197         if (impl == null)
 198             throw new NullPointerException();
 199         this.impl = impl;
 200         checkOldImpl();
 201     }
 202 
 203     /**
 204      * Creates a datagram socket, bound to the specified local
 205      * socket address.
 206      * <p>
 207      * If, if the address is <code>null</code>, creates an unbound socket.
 208      * <p>
 209      * <p>If there is a security manager,
 210      * its <code>checkListen</code> method is first called
 211      * with the port from the socket address
 212      * as its argument to ensure the operation is allowed.
 213      * This could result in a SecurityException.
 214      *
 215      * @param bindaddr local socket address to bind, or <code>null</code>
 216      *                 for an unbound socket.
 217      *
 218      * @exception  SocketException  if the socket could not be opened,
 219      *               or the socket could not bind to the specified local port.
 220      * @exception  SecurityException  if a security manager exists and its
 221      *             <code>checkListen</code> method doesn't allow the operation.
 222      *
 223      * @see SecurityManager#checkListen
 224      * @since   1.4
 225      */
 226     public DatagramSocket(SocketAddress bindaddr) throws SocketException {
 227         // create a datagram socket.
 228         createImpl();
 229         if (bindaddr != null) {
 230             bind(bindaddr);
 231         }
 232     }
 233 
 234     /**
 235      * Constructs a datagram socket and binds it to the specified port
 236      * on the local host machine.  The socket will be bound to the
 237      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 238      * an IP address chosen by the kernel.
 239      *
 240      * <p>If there is a security manager,
 241      * its <code>checkListen</code> method is first called
 242      * with the <code>port</code> argument
 243      * as its argument to ensure the operation is allowed.
 244      * This could result in a SecurityException.
 245      *
 246      * @param      port port to use.
 247      * @exception  SocketException  if the socket could not be opened,
 248      *               or the socket could not bind to the specified local port.
 249      * @exception  SecurityException  if a security manager exists and its
 250      *             <code>checkListen</code> method doesn't allow the operation.
 251      *
 252      * @see SecurityManager#checkListen
 253      */
 254     public DatagramSocket(int port) throws SocketException {
 255         this(port, null);
 256     }
 257 
 258     /**
 259      * Creates a datagram socket, bound to the specified local
 260      * address.  The local port must be between 0 and 65535 inclusive.
 261      * If the IP address is 0.0.0.0, the socket will be bound to the
 262      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 263      * an IP address chosen by the kernel.
 264      *
 265      * <p>If there is a security manager,
 266      * its <code>checkListen</code> method is first called
 267      * with the <code>port</code> argument
 268      * as its argument to ensure the operation is allowed.
 269      * This could result in a SecurityException.
 270      *
 271      * @param port local port to use
 272      * @param laddr local address to bind
 273      *
 274      * @exception  SocketException  if the socket could not be opened,
 275      *               or the socket could not bind to the specified local port.
 276      * @exception  SecurityException  if a security manager exists and its
 277      *             <code>checkListen</code> method doesn't allow the operation.
 278      *
 279      * @see SecurityManager#checkListen
 280      * @since   JDK1.1
 281      */
 282     public DatagramSocket(int port, InetAddress laddr) throws SocketException {
 283         this(new InetSocketAddress(laddr, port));
 284     }
 285 
 286     private void checkOldImpl() {
 287         if (impl == null)
 288             return;
 289         // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use
 290         // getDeclaredMethod, therefore we need permission to access the member
 291         try {
 292             AccessController.doPrivileged(
 293                 new PrivilegedExceptionAction<Void>() {
 294                     public Void run() throws NoSuchMethodException {
 295                         Class[] cl = new Class[1];
 296                         cl[0] = DatagramPacket.class;
 297                         impl.getClass().getDeclaredMethod("peekData", cl);
 298                         return null;
 299                     }
 300                 });
 301         } catch (java.security.PrivilegedActionException e) {
 302             oldImpl = true;
 303         }
 304     }
 305 
 306     static Class implClass = null;
 307 
 308     void createImpl() throws SocketException {
 309         if (impl == null) {
 310             if (factory != null) {
 311                 impl = factory.createDatagramSocketImpl();
 312                 checkOldImpl();
 313             } else {
 314                 boolean isMulticast = (this instanceof MulticastSocket) ? true : false;
 315                 impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(isMulticast);
 316 
 317                 checkOldImpl();
 318             }
 319         }
 320         // creates a udp socket
 321         impl.create();
 322         created = true;
 323     }
 324 
 325     /**
 326      * Get the <code>DatagramSocketImpl</code> attached to this socket,
 327      * creating it if necessary.
 328      *
 329      * @return  the <code>DatagramSocketImpl</code> attached to that
 330      *          DatagramSocket
 331      * @throws SocketException if creation fails.
 332      * @since 1.4
 333      */
 334     DatagramSocketImpl getImpl() throws SocketException {
 335         if (!created)
 336             createImpl();
 337         return impl;
 338     }
 339 
 340     /**
 341      * Binds this DatagramSocket to a specific address & port.
 342      * <p>
 343      * If the address is <code>null</code>, then the system will pick up
 344      * an ephemeral port and a valid local address to bind the socket.
 345      *<p>
 346      * @param   addr The address & port to bind to.
 347      * @throws  SocketException if any error happens during the bind, or if the
 348      *          socket is already bound.
 349      * @throws  SecurityException  if a security manager exists and its
 350      *             <code>checkListen</code> method doesn't allow the operation.
 351      * @throws IllegalArgumentException if addr is a SocketAddress subclass
 352      *         not supported by this socket.
 353      * @since 1.4
 354      */
 355     public synchronized void bind(SocketAddress addr) throws SocketException {
 356         if (isClosed())
 357             throw new SocketException("Socket is closed");
 358         if (isBound())
 359             throw new SocketException("already bound");
 360         if (addr == null)
 361             addr = new InetSocketAddress(0);
 362         if (!(addr instanceof InetSocketAddress))
 363             throw new IllegalArgumentException("Unsupported address type!");
 364         InetSocketAddress epoint = (InetSocketAddress) addr;
 365         if (epoint.isUnresolved())
 366             throw new SocketException("Unresolved address");
 367         InetAddress iaddr = epoint.getAddress();
 368         int port = epoint.getPort();
 369         checkAddress(iaddr, "bind");
 370         SecurityManager sec = System.getSecurityManager();
 371         if (sec != null) {
 372             sec.checkListen(port);
 373         }
 374         try {
 375             getImpl().bind(port, iaddr);
 376         } catch (SocketException e) {
 377             getImpl().close();
 378             throw e;
 379         }
 380         bound = true;
 381     }
 382 
 383     void checkAddress (InetAddress addr, String op) {
 384         if (addr == null) {
 385             return;
 386         }
 387         if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
 388             throw new IllegalArgumentException(op + ": invalid address type");
 389         }
 390     }
 391 
 392     /**
 393      * Connects the socket to a remote address for this socket. When a
 394      * socket is connected to a remote address, packets may only be
 395      * sent to or received from that address. By default a datagram
 396      * socket is not connected.
 397      *
 398      * <p>If the remote destination to which the socket is connected does not
 399      * exist, or is otherwise unreachable, and if an ICMP destination unreachable
 400      * packet has been received for that address, then a subsequent call to
 401      * send or receive may throw a PortUnreachableException. Note, there is no
 402      * guarantee that the exception will be thrown.
 403      *
 404      * <p> If a security manager has been installed then it is invoked to check
 405      * access to the remote address. Specifically, if the given {@code address}
 406      * is a {@link InetAddress#isMulticastAddress multicast address},
 407      * the security manager's {@link
 408      * java.lang.SecurityManager#checkMulticast(InetAddress)
 409      * checkMulticast} method is invoked with the given {@code address}.
 410      * Otherwise, the security manager's {@link
 411      * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
 412      * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
 413      * are invoked, with the given {@code address} and {@code port}, to
 414      * verify that datagrams are permitted to be sent and received
 415      * respectively.
 416      *
 417      * <p> When a socket is connected, {@link #receive receive} and
 418      * {@link #send send} <b>will not perform any security checks</b>
 419      * on incoming and outgoing packets, other than matching the packet's
 420      * and the socket's address and port. On a send operation, if the
 421      * packet's address is set and the packet's address and the socket's
 422      * address do not match, an {@code IllegalArgumentException} will be
 423      * thrown. A socket connected to a multicast address may only be used
 424      * to send packets.
 425      *
 426      * @param address the remote address for the socket
 427      *
 428      * @param port the remote port for the socket.
 429      *
 430      * @throws IllegalArgumentException
 431      *         if the address is null, or the port is out of range.
 432      *
 433      * @throws SecurityException
 434      *         if a security manager has been installed and it does
 435      *         not permit access to the given remote address
 436      *
 437      * @see #disconnect
 438      */
 439     public void connect(InetAddress address, int port) {
 440         try {
 441             connectInternal(address, port);
 442         } catch (SocketException se) {
 443             throw new Error("connect failed", se);
 444         }
 445     }
 446 
 447     /**
 448      * Connects this socket to a remote socket address (IP address + port number).
 449      *
 450      * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
 451      * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
 452      * with the the given socket addresses IP address and port number.
 453      *
 454      * @param   addr    The remote address.
 455      *
 456      * @throws  SocketException
 457      *          if the connect fails
 458      *
 459      * @throws IllegalArgumentException
 460      *         if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
 461      *         subclass not supported by this socket
 462      *
 463      * @throws SecurityException
 464      *         if a security manager has been installed and it does
 465      *         not permit access to the given remote address
 466      *
 467      * @since 1.4
 468      */
 469     public void connect(SocketAddress addr) throws SocketException {
 470         if (addr == null)
 471             throw new IllegalArgumentException("Address can't be null");
 472         if (!(addr instanceof InetSocketAddress))
 473             throw new IllegalArgumentException("Unsupported address type");
 474         InetSocketAddress epoint = (InetSocketAddress) addr;
 475         if (epoint.isUnresolved())
 476             throw new SocketException("Unresolved address");
 477         connectInternal(epoint.getAddress(), epoint.getPort());
 478     }
 479 
 480     /**
 481      * Disconnects the socket. If the socket is closed or not connected,
 482      * then this method has no effect.
 483      *
 484      * @see #connect
 485      */
 486     public void disconnect() {
 487         synchronized (this) {
 488             if (isClosed())
 489                 return;
 490             if (connectState == ST_CONNECTED) {
 491                 impl.disconnect ();
 492             }
 493             connectedAddress = null;
 494             connectedPort = -1;
 495             connectState = ST_NOT_CONNECTED;
 496         }
 497     }
 498 
 499     /**
 500      * Returns the binding state of the socket.
 501      * <p>
 502      * If the socket was bound prior to being {@link #close closed},
 503      * then this method will continue to return <code>true</code>
 504      * after the socket is closed.
 505      *
 506      * @return true if the socket successfully bound to an address
 507      * @since 1.4
 508      */
 509     public boolean isBound() {
 510         return bound;
 511     }
 512 
 513     /**
 514      * Returns the connection state of the socket.
 515      * <p>
 516      * If the socket was connected prior to being {@link #close closed},
 517      * then this method will continue to return <code>true</code>
 518      * after the socket is closed.
 519      *
 520      * @return true if the socket successfully connected to a server
 521      * @since 1.4
 522      */
 523     public boolean isConnected() {
 524         return connectState != ST_NOT_CONNECTED;
 525     }
 526 
 527     /**
 528      * Returns the address to which this socket is connected. Returns
 529      * <code>null</code> if the socket is not connected.
 530      * <p>
 531      * If the socket was connected prior to being {@link #close closed},
 532      * then this method will continue to return the connected address
 533      * after the socket is closed.
 534      *
 535      * @return the address to which this socket is connected.
 536      */
 537     public InetAddress getInetAddress() {
 538         return connectedAddress;
 539     }
 540 
 541     /**
 542      * Returns the port number to which this socket is connected.
 543      * Returns <code>-1</code> if the socket is not connected.
 544      * <p>
 545      * If the socket was connected prior to being {@link #close closed},
 546      * then this method will continue to return the connected port number
 547      * after the socket is closed.
 548      *
 549      * @return the port number to which this socket is connected.
 550      */
 551     public int getPort() {
 552         return connectedPort;
 553     }
 554 
 555     /**
 556      * Returns the address of the endpoint this socket is connected to, or
 557      * <code>null</code> if it is unconnected.
 558      * <p>
 559      * If the socket was connected prior to being {@link #close closed},
 560      * then this method will continue to return the connected address
 561      * after the socket is closed.
 562      *
 563      * @return a <code>SocketAddress</code> representing the remote
 564      *         endpoint of this socket, or <code>null</code> if it is
 565      *         not connected yet.
 566      * @see #getInetAddress()
 567      * @see #getPort()
 568      * @see #connect(SocketAddress)
 569      * @since 1.4
 570      */
 571     public SocketAddress getRemoteSocketAddress() {
 572         if (!isConnected())
 573             return null;
 574         return new InetSocketAddress(getInetAddress(), getPort());
 575     }
 576 
 577     /**
 578      * Returns the address of the endpoint this socket is bound to.
 579      *
 580      * @return a <code>SocketAddress</code> representing the local endpoint of this
 581      *         socket, or <code>null</code> if it is closed or not bound yet.
 582      * @see #getLocalAddress()
 583      * @see #getLocalPort()
 584      * @see #bind(SocketAddress)
 585      * @since 1.4
 586      */
 587 
 588     public SocketAddress getLocalSocketAddress() {
 589         if (isClosed())
 590             return null;
 591         if (!isBound())
 592             return null;
 593         return new InetSocketAddress(getLocalAddress(), getLocalPort());
 594     }
 595 
 596     /**
 597      * Sends a datagram packet from this socket. The
 598      * <code>DatagramPacket</code> includes information indicating the
 599      * data to be sent, its length, the IP address of the remote host,
 600      * and the port number on the remote host.
 601      *
 602      * <p>If there is a security manager, and the socket is not currently
 603      * connected to a remote address, this method first performs some
 604      * security checks. First, if <code>p.getAddress().isMulticastAddress()</code>
 605      * is true, this method calls the
 606      * security manager's <code>checkMulticast</code> method
 607      * with <code>p.getAddress()</code> as its argument.
 608      * If the evaluation of that expression is false,
 609      * this method instead calls the security manager's
 610      * <code>checkConnect</code> method with arguments
 611      * <code>p.getAddress().getHostAddress()</code> and
 612      * <code>p.getPort()</code>. Each call to a security manager method
 613      * could result in a SecurityException if the operation is not allowed.
 614      *
 615      * @param      p   the <code>DatagramPacket</code> to be sent.
 616      *
 617      * @exception  IOException  if an I/O error occurs.
 618      * @exception  SecurityException  if a security manager exists and its
 619      *             <code>checkMulticast</code> or <code>checkConnect</code>
 620      *             method doesn't allow the send.
 621      * @exception  PortUnreachableException may be thrown if the socket is connected
 622      *             to a currently unreachable destination. Note, there is no
 623      *             guarantee that the exception will be thrown.
 624      * @exception  java.nio.channels.IllegalBlockingModeException
 625      *             if this socket has an associated channel,
 626      *             and the channel is in non-blocking mode.
 627      * @exception  IllegalArgumentException if the socket is connected,
 628      *             and connected address and packet address differ.
 629      *
 630      * @see        java.net.DatagramPacket
 631      * @see        SecurityManager#checkMulticast(InetAddress)
 632      * @see        SecurityManager#checkConnect
 633      * @revised 1.4
 634      * @spec JSR-51
 635      */
 636     public void send(DatagramPacket p) throws IOException  {
 637         InetAddress packetAddress = null;
 638         synchronized (p) {
 639             if (isClosed())
 640                 throw new SocketException("Socket is closed");
 641             checkAddress (p.getAddress(), "send");
 642             if (connectState == ST_NOT_CONNECTED) {
 643                 // check the address is ok wiht the security manager on every send.
 644                 SecurityManager security = System.getSecurityManager();
 645 
 646                 // The reason you want to synchronize on datagram packet
 647                 // is because you dont want an applet to change the address
 648                 // while you are trying to send the packet for example
 649                 // after the security check but before the send.
 650                 if (security != null) {
 651                     if (p.getAddress().isMulticastAddress()) {
 652                         security.checkMulticast(p.getAddress());
 653                     } else {
 654                         security.checkConnect(p.getAddress().getHostAddress(),
 655                                               p.getPort());
 656                     }
 657                 }
 658             } else {
 659                 // we're connected
 660                 packetAddress = p.getAddress();
 661                 if (packetAddress == null) {
 662                     p.setAddress(connectedAddress);
 663                     p.setPort(connectedPort);
 664                 } else if ((!packetAddress.equals(connectedAddress)) ||
 665                            p.getPort() != connectedPort) {
 666                     throw new IllegalArgumentException("connected address " +
 667                                                        "and packet address" +
 668                                                        " differ");
 669                 }
 670             }
 671             // Check whether the socket is bound
 672             if (!isBound())
 673                 bind(new InetSocketAddress(0));
 674             // call the  method to send
 675             getImpl().send(p);
 676         }
 677     }
 678 
 679     /**
 680      * Receives a datagram packet from this socket. When this method
 681      * returns, the <code>DatagramPacket</code>'s buffer is filled with
 682      * the data received. The datagram packet also contains the sender's
 683      * IP address, and the port number on the sender's machine.
 684      * <p>
 685      * This method blocks until a datagram is received. The
 686      * <code>length</code> field of the datagram packet object contains
 687      * the length of the received message. If the message is longer than
 688      * the packet's length, the message is truncated.
 689      * <p>
 690      * If there is a security manager, a packet cannot be received if the
 691      * security manager's <code>checkAccept</code> method
 692      * does not allow it.
 693      *
 694      * @param      p   the <code>DatagramPacket</code> into which to place
 695      *                 the incoming data.
 696      * @exception  IOException  if an I/O error occurs.
 697      * @exception  SocketTimeoutException  if setSoTimeout was previously called
 698      *                 and the timeout has expired.
 699      * @exception  PortUnreachableException may be thrown if the socket is connected
 700      *             to a currently unreachable destination. Note, there is no guarantee that the
 701      *             exception will be thrown.
 702      * @exception  java.nio.channels.IllegalBlockingModeException
 703      *             if this socket has an associated channel,
 704      *             and the channel is in non-blocking mode.
 705      * @see        java.net.DatagramPacket
 706      * @see        java.net.DatagramSocket
 707      * @revised 1.4
 708      * @spec JSR-51
 709      */
 710     public synchronized void receive(DatagramPacket p) throws IOException {
 711         synchronized (p) {
 712             if (!isBound())
 713                 bind(new InetSocketAddress(0));
 714             if (connectState == ST_NOT_CONNECTED) {
 715                 // check the address is ok with the security manager before every recv.
 716                 SecurityManager security = System.getSecurityManager();
 717                 if (security != null) {
 718                     while(true) {
 719                         String peekAd = null;
 720                         int peekPort = 0;
 721                         // peek at the packet to see who it is from.
 722                         if (!oldImpl) {
 723                             // We can use the new peekData() API
 724                             DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
 725                             peekPort = getImpl().peekData(peekPacket);
 726                             peekAd = peekPacket.getAddress().getHostAddress();
 727                         } else {
 728                             InetAddress adr = new InetAddress();
 729                             peekPort = getImpl().peek(adr);
 730                             peekAd = adr.getHostAddress();
 731                         }
 732                         try {
 733                             security.checkAccept(peekAd, peekPort);
 734                             // security check succeeded - so now break
 735                             // and recv the packet.
 736                             break;
 737                         } catch (SecurityException se) {
 738                             // Throw away the offending packet by consuming
 739                             // it in a tmp buffer.
 740                             DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
 741                             getImpl().receive(tmp);
 742 
 743                             // silently discard the offending packet
 744                             // and continue: unknown/malicious
 745                             // entities on nets should not make
 746                             // runtime throw security exception and
 747                             // disrupt the applet by sending random
 748                             // datagram packets.
 749                             continue;
 750                         }
 751                     } // end of while
 752                 }
 753             }
 754             if (connectState == ST_CONNECTED_NO_IMPL) {
 755                 // We have to do the filtering the old fashioned way since
 756                 // the native impl doesn't support connect or the connect
 757                 // via the impl failed.
 758                 boolean stop = false;
 759                 while (!stop) {
 760                     // peek at the packet to see who it is from.
 761                     InetAddress peekAddress = new InetAddress();
 762                     int peekPort = getImpl().peek(peekAddress);
 763                     if ((!connectedAddress.equals(peekAddress)) ||
 764                         (connectedPort != peekPort)) {
 765                         // throw the packet away and silently continue
 766                         DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
 767                         getImpl().receive(tmp);
 768                     } else {
 769                         stop = true;
 770                     }
 771                 }
 772             }
 773             // If the security check succeeds, or the datagram is
 774             // connected then receive the packet
 775             getImpl().receive(p);
 776         }
 777     }
 778 
 779     /**
 780      * Gets the local address to which the socket is bound.
 781      *
 782      * <p>If there is a security manager, its
 783      * <code>checkConnect</code> method is first called
 784      * with the host address and <code>-1</code>
 785      * as its arguments to see if the operation is allowed.
 786      *
 787      * @see SecurityManager#checkConnect
 788      * @return  the local address to which the socket is bound,
 789      *          <code>null</code> if the socket is closed, or
 790      *          an <code>InetAddress</code> representing
 791      *          {@link InetAddress#isAnyLocalAddress wildcard}
 792      *          address if either the socket is not bound, or
 793      *          the security manager <code>checkConnect</code>
 794      *          method does not allow the operation
 795      * @since   1.1
 796      */
 797     public InetAddress getLocalAddress() {
 798         if (isClosed())
 799             return null;
 800         InetAddress in = null;
 801         try {
 802             in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
 803             if (in.isAnyLocalAddress()) {
 804                 in = InetAddress.anyLocalAddress();
 805             }
 806             SecurityManager s = System.getSecurityManager();
 807             if (s != null) {
 808                 s.checkConnect(in.getHostAddress(), -1);
 809             }
 810         } catch (Exception e) {
 811             in = InetAddress.anyLocalAddress(); // "0.0.0.0"
 812         }
 813         return in;
 814     }
 815 
 816     /**
 817      * Returns the port number on the local host to which this socket
 818      * is bound.
 819      *
 820      * @return  the port number on the local host to which this socket is bound,
 821                 <code>-1</code> if the socket is closed, or
 822                 <code>0</code> if it is not bound yet.
 823      */
 824     public int getLocalPort() {
 825         if (isClosed())
 826             return -1;
 827         try {
 828             return getImpl().getLocalPort();
 829         } catch (Exception e) {
 830             return 0;
 831         }
 832     }
 833 
 834     /** Enable/disable SO_TIMEOUT with the specified timeout, in
 835      *  milliseconds. With this option set to a non-zero timeout,
 836      *  a call to receive() for this DatagramSocket
 837      *  will block for only this amount of time.  If the timeout expires,
 838      *  a <B>java.net.SocketTimeoutException</B> is raised, though the
 839      *  DatagramSocket is still valid.  The option <B>must</B> be enabled
 840      *  prior to entering the blocking operation to have effect.  The
 841      *  timeout must be > 0.
 842      *  A timeout of zero is interpreted as an infinite timeout.
 843      *
 844      * @param timeout the specified timeout in milliseconds.
 845      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
 846      * @since   JDK1.1
 847      * @see #getSoTimeout()
 848      */
 849     public synchronized void setSoTimeout(int timeout) throws SocketException {
 850         if (isClosed())
 851             throw new SocketException("Socket is closed");
 852         getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
 853     }
 854 
 855     /**
 856      * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
 857      * option is disabled (i.e., timeout of infinity).
 858      *
 859      * @return the setting for SO_TIMEOUT
 860      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
 861      * @since   JDK1.1
 862      * @see #setSoTimeout(int)
 863      */
 864     public synchronized int getSoTimeout() throws SocketException {
 865         if (isClosed())
 866             throw new SocketException("Socket is closed");
 867         if (getImpl() == null)
 868             return 0;
 869         Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
 870         /* extra type safety */
 871         if (o instanceof Integer) {
 872             return ((Integer) o).intValue();
 873         } else {
 874             return 0;
 875         }
 876     }
 877 
 878     /**
 879      * Sets the SO_SNDBUF option to the specified value for this
 880      * <tt>DatagramSocket</tt>. The SO_SNDBUF option is used by the
 881      * network implementation as a hint to size the underlying
 882      * network I/O buffers. The SO_SNDBUF setting may also be used
 883      * by the network implementation to determine the maximum size
 884      * of the packet that can be sent on this socket.
 885      * <p>
 886      * As SO_SNDBUF is a hint, applications that want to verify
 887      * what size the buffer is should call {@link #getSendBufferSize()}.
 888      * <p>
 889      * Increasing the buffer size may allow multiple outgoing packets
 890      * to be queued by the network implementation when the send rate
 891      * is high.
 892      * <p>
 893      * Note: If {@link #send(DatagramPacket)} is used to send a
 894      * <code>DatagramPacket</code> that is larger than the setting
 895      * of SO_SNDBUF then it is implementation specific if the
 896      * packet is sent or discarded.
 897      *
 898      * @param size the size to which to set the send buffer
 899      * size. This value must be greater than 0.
 900      *
 901      * @exception SocketException if there is an error
 902      * in the underlying protocol, such as an UDP error.
 903      * @exception IllegalArgumentException if the value is 0 or is
 904      * negative.
 905      * @see #getSendBufferSize()
 906      */
 907     public synchronized void setSendBufferSize(int size)
 908     throws SocketException{
 909         if (!(size > 0)) {
 910             throw new IllegalArgumentException("negative send size");
 911         }
 912         if (isClosed())
 913             throw new SocketException("Socket is closed");
 914         getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
 915     }
 916 
 917     /**
 918      * Get value of the SO_SNDBUF option for this <tt>DatagramSocket</tt>, that is the
 919      * buffer size used by the platform for output on this <tt>DatagramSocket</tt>.
 920      *
 921      * @return the value of the SO_SNDBUF option for this <tt>DatagramSocket</tt>
 922      * @exception SocketException if there is an error in
 923      * the underlying protocol, such as an UDP error.
 924      * @see #setSendBufferSize
 925      */
 926     public synchronized int getSendBufferSize() throws SocketException {
 927         if (isClosed())
 928             throw new SocketException("Socket is closed");
 929         int result = 0;
 930         Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
 931         if (o instanceof Integer) {
 932             result = ((Integer)o).intValue();
 933         }
 934         return result;
 935     }
 936 
 937     /**
 938      * Sets the SO_RCVBUF option to the specified value for this
 939      * <tt>DatagramSocket</tt>. The SO_RCVBUF option is used by the
 940      * the network implementation as a hint to size the underlying
 941      * network I/O buffers. The SO_RCVBUF setting may also be used
 942      * by the network implementation to determine the maximum size
 943      * of the packet that can be received on this socket.
 944      * <p>
 945      * Because SO_RCVBUF is a hint, applications that want to
 946      * verify what size the buffers were set to should call
 947      * {@link #getReceiveBufferSize()}.
 948      * <p>
 949      * Increasing SO_RCVBUF may allow the network implementation
 950      * to buffer multiple packets when packets arrive faster than
 951      * are being received using {@link #receive(DatagramPacket)}.
 952      * <p>
 953      * Note: It is implementation specific if a packet larger
 954      * than SO_RCVBUF can be received.
 955      *
 956      * @param size the size to which to set the receive buffer
 957      * size. This value must be greater than 0.
 958      *
 959      * @exception SocketException if there is an error in
 960      * the underlying protocol, such as an UDP error.
 961      * @exception IllegalArgumentException if the value is 0 or is
 962      * negative.
 963      * @see #getReceiveBufferSize()
 964      */
 965     public synchronized void setReceiveBufferSize(int size)
 966     throws SocketException{
 967         if (size <= 0) {
 968             throw new IllegalArgumentException("invalid receive size");
 969         }
 970         if (isClosed())
 971             throw new SocketException("Socket is closed");
 972         getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
 973     }
 974 
 975     /**
 976      * Get value of the SO_RCVBUF option for this <tt>DatagramSocket</tt>, that is the
 977      * buffer size used by the platform for input on this <tt>DatagramSocket</tt>.
 978      *
 979      * @return the value of the SO_RCVBUF option for this <tt>DatagramSocket</tt>
 980      * @exception SocketException if there is an error in the underlying protocol, such as an UDP error.
 981      * @see #setReceiveBufferSize(int)
 982      */
 983     public synchronized int getReceiveBufferSize()
 984     throws SocketException{
 985         if (isClosed())
 986             throw new SocketException("Socket is closed");
 987         int result = 0;
 988         Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
 989         if (o instanceof Integer) {
 990             result = ((Integer)o).intValue();
 991         }
 992         return result;
 993     }
 994 
 995     /**
 996      * Enable/disable the SO_REUSEADDR socket option.
 997      * <p>
 998      * For UDP sockets it may be necessary to bind more than one
 999      * socket to the same socket address. This is typically for the
1000      * purpose of receiving multicast packets
1001      * (See {@link java.net.MulticastSocket}). The
1002      * <tt>SO_REUSEADDR</tt> socket option allows multiple
1003      * sockets to be bound to the same socket address if the
1004      * <tt>SO_REUSEADDR</tt> socket option is enabled prior
1005      * to binding the socket using {@link #bind(SocketAddress)}.
1006      * <p>
1007      * Note: This functionality is not supported by all existing platforms,
1008      * so it is implementation specific whether this option will be ignored
1009      * or not. However, if it is not supported then
1010      * {@link #getReuseAddress()} will always return <code>false</code>.
1011      * <p>
1012      * When a <tt>DatagramSocket</tt> is created the initial setting
1013      * of <tt>SO_REUSEADDR</tt> is disabled.
1014      * <p>
1015      * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
1016      * disabled after a socket is bound (See {@link #isBound()})
1017      * is not defined.
1018      *
1019      * @param on  whether to enable or disable the
1020      * @exception SocketException if an error occurs enabling or
1021      *            disabling the <tt>SO_RESUEADDR</tt> socket option,
1022      *            or the socket is closed.
1023      * @since 1.4
1024      * @see #getReuseAddress()
1025      * @see #bind(SocketAddress)
1026      * @see #isBound()
1027      * @see #isClosed()
1028      */
1029     public synchronized void setReuseAddress(boolean on) throws SocketException {
1030         if (isClosed())
1031             throw new SocketException("Socket is closed");
1032         // Integer instead of Boolean for compatibility with older DatagramSocketImpl
1033         if (oldImpl)
1034             getImpl().setOption(SocketOptions.SO_REUSEADDR, new Integer(on?-1:0));
1035         else
1036             getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
1037     }
1038 
1039     /**
1040      * Tests if SO_REUSEADDR is enabled.
1041      *
1042      * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
1043      * @exception SocketException if there is an error
1044      * in the underlying protocol, such as an UDP error.
1045      * @since   1.4
1046      * @see #setReuseAddress(boolean)
1047      */
1048     public synchronized boolean getReuseAddress() throws SocketException {
1049         if (isClosed())
1050             throw new SocketException("Socket is closed");
1051         Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
1052         return ((Boolean)o).booleanValue();
1053     }
1054 
1055     /**
1056      * Enable/disable SO_BROADCAST.
1057      *
1058      * <p> Some operating systems may require that the Java virtual machine be
1059      * started with implementation specific privileges to enable this option or
1060      * send broadcast datagrams.
1061      *
1062      * @param  on
1063      *         whether or not to have broadcast turned on.
1064      *
1065      * @throws  SocketException
1066      *          if there is an error in the underlying protocol, such as an UDP
1067      *          error.
1068      *
1069      * @since 1.4
1070      * @see #getBroadcast()
1071      */
1072     public synchronized void setBroadcast(boolean on) throws SocketException {
1073         if (isClosed())
1074             throw new SocketException("Socket is closed");
1075         getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on));
1076     }
1077 
1078     /**
1079      * Tests if SO_BROADCAST is enabled.
1080      * @return a <code>boolean</code> indicating whether or not SO_BROADCAST is enabled.
1081      * @exception SocketException if there is an error
1082      * in the underlying protocol, such as an UDP error.
1083      * @since 1.4
1084      * @see #setBroadcast(boolean)
1085      */
1086     public synchronized boolean getBroadcast() throws SocketException {
1087         if (isClosed())
1088             throw new SocketException("Socket is closed");
1089         return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue();
1090     }
1091 
1092     /**
1093      * Sets traffic class or type-of-service octet in the IP
1094      * datagram header for datagrams sent from this DatagramSocket.
1095      * As the underlying network implementation may ignore this
1096      * value applications should consider it a hint.
1097      *
1098      * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
1099      * 255</code> or an IllegalArgumentException will be thrown.
1100      * <p>Notes:
1101      * <p>For Internet Protocol v4 the value consists of an
1102      * <code>integer</code>, the least significant 8 bits of which
1103      * represent the value of the TOS octet in IP packets sent by
1104      * the socket.
1105      * RFC 1349 defines the TOS values as follows:
1106      * <p>
1107      * <UL>
1108      * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1109      * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1110      * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1111      * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1112      * </UL>
1113      * The last low order bit is always ignored as this
1114      * corresponds to the MBZ (must be zero) bit.
1115      * <p>
1116      * Setting bits in the precedence field may result in a
1117      * SocketException indicating that the operation is not
1118      * permitted.
1119      * <p>
1120      * for Internet Protocol v6 <code>tc</code> is the value that
1121      * would be placed into the sin6_flowinfo field of the IP header.
1122      *
1123      * @param tc        an <code>int</code> value for the bitset.
1124      * @throws SocketException if there is an error setting the
1125      * traffic class or type-of-service
1126      * @since 1.4
1127      * @see #getTrafficClass
1128      */
1129     public synchronized void setTrafficClass(int tc) throws SocketException {
1130         if (tc < 0 || tc > 255)
1131             throw new IllegalArgumentException("tc is not in range 0 -- 255");
1132 
1133         if (isClosed())
1134             throw new SocketException("Socket is closed");
1135         getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
1136     }
1137 
1138     /**
1139      * Gets traffic class or type-of-service in the IP datagram
1140      * header for packets sent from this DatagramSocket.
1141      * <p>
1142      * As the underlying network implementation may ignore the
1143      * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1144      * this method may return a different value than was previously
1145      * set using the {@link #setTrafficClass(int)} method on this
1146      * DatagramSocket.
1147      *
1148      * @return the traffic class or type-of-service already set
1149      * @throws SocketException if there is an error obtaining the
1150      * traffic class or type-of-service value.
1151      * @since 1.4
1152      * @see #setTrafficClass(int)
1153      */
1154     public synchronized int getTrafficClass() throws SocketException {
1155         if (isClosed())
1156             throw new SocketException("Socket is closed");
1157         return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue();
1158     }
1159 
1160     /**
1161      * Closes this datagram socket.
1162      * <p>
1163      * Any thread currently blocked in {@link #receive} upon this socket
1164      * will throw a {@link SocketException}.
1165      *
1166      * <p> If this socket has an associated channel then the channel is closed
1167      * as well.
1168      *
1169      * @revised 1.4
1170      * @spec JSR-51
1171      */
1172     public void close() {
1173         synchronized(closeLock) {
1174             if (isClosed())
1175                 return;
1176             impl.close();
1177             closed = true;
1178         }
1179     }
1180 
1181     /**
1182      * Returns whether the socket is closed or not.
1183      *
1184      * @return true if the socket has been closed
1185      * @since 1.4
1186      */
1187     public boolean isClosed() {
1188         synchronized(closeLock) {
1189             return closed;
1190         }
1191     }
1192 
1193     /**
1194      * Returns the unique {@link java.nio.channels.DatagramChannel} object
1195      * associated with this datagram socket, if any.
1196      *
1197      * <p> A datagram socket will have a channel if, and only if, the channel
1198      * itself was created via the {@link java.nio.channels.DatagramChannel#open
1199      * DatagramChannel.open} method.
1200      *
1201      * @return  the datagram channel associated with this datagram socket,
1202      *          or <tt>null</tt> if this socket was not created for a channel
1203      *
1204      * @since 1.4
1205      * @spec JSR-51
1206      */
1207     public DatagramChannel getChannel() {
1208         return null;
1209     }
1210 
1211     /**
1212      * User defined factory for all datagram sockets.
1213      */
1214     static DatagramSocketImplFactory factory;
1215 
1216     /**
1217      * Sets the datagram socket implementation factory for the
1218      * application. The factory can be specified only once.
1219      * <p>
1220      * When an application creates a new datagram socket, the socket
1221      * implementation factory's <code>createDatagramSocketImpl</code> method is
1222      * called to create the actual datagram socket implementation.
1223      * <p>
1224      * Passing <code>null</code> to the method is a no-op unless the factory
1225      * was already set.
1226      *
1227      * <p>If there is a security manager, this method first calls
1228      * the security manager's <code>checkSetFactory</code> method
1229      * to ensure the operation is allowed.
1230      * This could result in a SecurityException.
1231      *
1232      * @param      fac   the desired factory.
1233      * @exception  IOException  if an I/O error occurs when setting the
1234      *              datagram socket factory.
1235      * @exception  SocketException  if the factory is already defined.
1236      * @exception  SecurityException  if a security manager exists and its
1237      *             <code>checkSetFactory</code> method doesn't allow the
1238      operation.
1239      * @see
1240      java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
1241      * @see       SecurityManager#checkSetFactory
1242      * @since 1.3
1243      */
1244     public static synchronized void
1245     setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
1246        throws IOException
1247     {
1248         if (factory != null) {
1249             throw new SocketException("factory already defined");
1250         }
1251         SecurityManager security = System.getSecurityManager();
1252         if (security != null) {
1253             security.checkSetFactory();
1254         }
1255         factory = fac;
1256     }
1257 }