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