• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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