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