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