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