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