1 /*
2 * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
98 * <th scope="row"> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </th>
99 * <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
100 * </tr>
101 * </tbody>
102 * </table>
103 * </blockquote>
104 * An implementation may also support additional options. In particular an implementation
105 * may support <a href="MulticastSocket.html#MulticastOptions">multicast options</a> which
106 * can be useful when using a plain {@code DatagramSocket} to send datagrams to a
107 * multicast group.
108 *
109 * @author Pavani Diwanji
110 * @see java.net.DatagramPacket
111 * @see java.nio.channels.DatagramChannel
112 * @since 1.0
113 */
114 public class DatagramSocket implements java.io.Closeable {
115 /**
116 * Various states of this socket.
117 */
118 private boolean created = false;
119 private boolean bound = false;
120 private boolean closed = false;
121 private Object closeLock = new Object();
122
123 /*
124 * The implementation of this DatagramSocket.
125 */
126 DatagramSocketImpl impl;
127
128 /**
129 * Are we using an older DatagramSocketImpl?
130 */
131 boolean oldImpl = false;
132
133 /**
134 * Set when a socket is ST_CONNECTED until we are certain
135 * that any packets which might have been received prior
136 * to calling connect() but not read by the application
137 * have been read. During this time we check the source
138 * address of all packets received to be sure they are from
139 * the connected destination. Other packets are read but
140 * silently dropped.
141 */
142 private boolean explicitFilter = false;
143 private int bytesLeftToFilter;
144 /*
145 * Connection state:
146 * ST_NOT_CONNECTED = socket not connected
265 * If, if the address is {@code null}, creates an unbound socket.
266 *
267 * <p>If there is a security manager,
268 * its {@code checkListen} method is first called
269 * with the port from the socket address
270 * as its argument to ensure the operation is allowed.
271 * This could result in a SecurityException.
272 *
273 * @param bindaddr local socket address to bind, or {@code null}
274 * for an unbound socket.
275 *
276 * @throws SocketException if the socket could not be opened,
277 * or the socket could not bind to the specified local port.
278 * @throws SecurityException if a security manager exists and its
279 * {@code checkListen} method doesn't allow the operation.
280 *
281 * @see SecurityManager#checkListen
282 * @since 1.4
283 */
284 public DatagramSocket(SocketAddress bindaddr) throws SocketException {
285 // create a datagram socket.
286 createImpl();
287 if (bindaddr != null) {
288 try {
289 bind(bindaddr);
290 } finally {
291 if (!isBound())
292 close();
293 }
294 }
295 }
296
297 /**
298 * Constructs a datagram socket and binds it to the specified port
299 * on the local host machine. The socket will be bound to the
300 * {@link InetAddress#isAnyLocalAddress wildcard} address,
301 * an IP address chosen by the kernel.
302 *
303 * <p>If there is a security manager,
304 * its {@code checkListen} method is first called
305 * with the {@code port} argument
306 * as its argument to ensure the operation is allowed.
351 return;
352 // DatagramSocketImpl.peekData() is a protected method, therefore we need to use
353 // getDeclaredMethod, therefore we need permission to access the member
354 try {
355 AccessController.doPrivileged(
356 new PrivilegedExceptionAction<>() {
357 public Void run() throws NoSuchMethodException {
358 Class<?>[] cl = new Class<?>[1];
359 cl[0] = DatagramPacket.class;
360 impl.getClass().getDeclaredMethod("peekData", cl);
361 return null;
362 }
363 });
364 } catch (java.security.PrivilegedActionException e) {
365 oldImpl = true;
366 }
367 }
368
369 static Class<?> implClass = null;
370
371 void createImpl() throws SocketException {
372 if (impl == null) {
373 if (factory != null) {
374 impl = factory.createDatagramSocketImpl();
375 checkOldImpl();
376 } else {
377 boolean isMulticast = (this instanceof MulticastSocket) ? true : false;
378 impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(isMulticast);
379
380 checkOldImpl();
381 }
382 }
383 // creates a udp socket
384 impl.create();
385 created = true;
386 }
387
388 /**
389 * Get the {@code DatagramSocketImpl} attached to this socket,
390 * creating it if necessary.
391 *
392 * @return the {@code DatagramSocketImpl} attached to that
393 * DatagramSocket
394 * @throws SocketException if creation fails.
395 * @since 1.4
396 */
397 DatagramSocketImpl getImpl() throws SocketException {
398 if (!created)
399 createImpl();
400 return impl;
401 }
402
403 /**
404 * Binds this DatagramSocket to a specific address and port.
405 * <p>
406 * If the address is {@code null}, then the system will pick up
407 * an ephemeral port and a valid local address to bind the socket.
408 *
409 * @param addr The address and port to bind to.
410 * @throws SocketException if any error happens during the bind, or if the
411 * socket is already bound.
412 * @throws SecurityException if a security manager exists and its
413 * {@code checkListen} method doesn't allow the operation.
414 * @throws IllegalArgumentException if addr is a SocketAddress subclass
415 * not supported by this socket.
416 * @since 1.4
417 */
418 public synchronized void bind(SocketAddress addr) throws SocketException {
419 if (isClosed())
1304 * Returns the unique {@link java.nio.channels.DatagramChannel} object
1305 * associated with this datagram socket, if any.
1306 *
1307 * <p> A datagram socket will have a channel if, and only if, the channel
1308 * itself was created via the {@link java.nio.channels.DatagramChannel#open
1309 * DatagramChannel.open} method.
1310 *
1311 * @return the datagram channel associated with this datagram socket,
1312 * or {@code null} if this socket was not created for a channel
1313 *
1314 * @since 1.4
1315 * @spec JSR-51
1316 */
1317 public DatagramChannel getChannel() {
1318 return null;
1319 }
1320
1321 /**
1322 * User defined factory for all datagram sockets.
1323 */
1324 static DatagramSocketImplFactory factory;
1325
1326 /**
1327 * Sets the datagram socket implementation factory for the
1328 * application. The factory can be specified only once.
1329 * <p>
1330 * When an application creates a new datagram socket, the socket
1331 * implementation factory's {@code createDatagramSocketImpl} method is
1332 * called to create the actual datagram socket implementation.
1333 * <p>
1334 * Passing {@code null} to the method is a no-op unless the factory
1335 * was already set.
1336 *
1337 * <p>If there is a security manager, this method first calls
1338 * the security manager's {@code checkSetFactory} method
1339 * to ensure the operation is allowed.
1340 * This could result in a SecurityException.
1341 *
1342 * @param fac the desired factory.
1343 * @throws IOException if an I/O error occurs when setting the
1344 * datagram socket factory.
|
1 /*
2 * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
98 * <th scope="row"> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </th>
99 * <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
100 * </tr>
101 * </tbody>
102 * </table>
103 * </blockquote>
104 * An implementation may also support additional options. In particular an implementation
105 * may support <a href="MulticastSocket.html#MulticastOptions">multicast options</a> which
106 * can be useful when using a plain {@code DatagramSocket} to send datagrams to a
107 * multicast group.
108 *
109 * @author Pavani Diwanji
110 * @see java.net.DatagramPacket
111 * @see java.nio.channels.DatagramChannel
112 * @since 1.0
113 */
114 public class DatagramSocket implements java.io.Closeable {
115 /**
116 * Various states of this socket.
117 */
118 private boolean bound = false;
119 private boolean closed = false;
120 private Object closeLock = new Object();
121
122 /*
123 * The implementation of this DatagramSocket.
124 */
125 private final DatagramSocketImpl impl;
126
127 /**
128 * Are we using an older DatagramSocketImpl?
129 */
130 boolean oldImpl = false;
131
132 /**
133 * Set when a socket is ST_CONNECTED until we are certain
134 * that any packets which might have been received prior
135 * to calling connect() but not read by the application
136 * have been read. During this time we check the source
137 * address of all packets received to be sure they are from
138 * the connected destination. Other packets are read but
139 * silently dropped.
140 */
141 private boolean explicitFilter = false;
142 private int bytesLeftToFilter;
143 /*
144 * Connection state:
145 * ST_NOT_CONNECTED = socket not connected
264 * If, if the address is {@code null}, creates an unbound socket.
265 *
266 * <p>If there is a security manager,
267 * its {@code checkListen} method is first called
268 * with the port from the socket address
269 * as its argument to ensure the operation is allowed.
270 * This could result in a SecurityException.
271 *
272 * @param bindaddr local socket address to bind, or {@code null}
273 * for an unbound socket.
274 *
275 * @throws SocketException if the socket could not be opened,
276 * or the socket could not bind to the specified local port.
277 * @throws SecurityException if a security manager exists and its
278 * {@code checkListen} method doesn't allow the operation.
279 *
280 * @see SecurityManager#checkListen
281 * @since 1.4
282 */
283 public DatagramSocket(SocketAddress bindaddr) throws SocketException {
284 // Special case initialization for the DatagramChannel socket adaptor.
285 if (this instanceof sun.nio.ch.DatagramSocketAdaptor) {
286 this.impl = null; // no DatagramSocketImpl
287 return;
288 }
289
290 // create a datagram socket.
291 boolean multicast = (this instanceof MulticastSocket);
292 this.impl = createImpl(multicast);
293 checkOldImpl();
294 if (bindaddr != null) {
295 try {
296 bind(bindaddr);
297 } finally {
298 if (!isBound())
299 close();
300 }
301 }
302 }
303
304 /**
305 * Constructs a datagram socket and binds it to the specified port
306 * on the local host machine. The socket will be bound to the
307 * {@link InetAddress#isAnyLocalAddress wildcard} address,
308 * an IP address chosen by the kernel.
309 *
310 * <p>If there is a security manager,
311 * its {@code checkListen} method is first called
312 * with the {@code port} argument
313 * as its argument to ensure the operation is allowed.
358 return;
359 // DatagramSocketImpl.peekData() is a protected method, therefore we need to use
360 // getDeclaredMethod, therefore we need permission to access the member
361 try {
362 AccessController.doPrivileged(
363 new PrivilegedExceptionAction<>() {
364 public Void run() throws NoSuchMethodException {
365 Class<?>[] cl = new Class<?>[1];
366 cl[0] = DatagramPacket.class;
367 impl.getClass().getDeclaredMethod("peekData", cl);
368 return null;
369 }
370 });
371 } catch (java.security.PrivilegedActionException e) {
372 oldImpl = true;
373 }
374 }
375
376 static Class<?> implClass = null;
377
378 /**
379 * Creates a DatagramSocketImpl.
380 * @param multicast true if the DatagramSocketImpl is for a MulticastSocket
381 */
382 private static DatagramSocketImpl createImpl(boolean multicast) throws SocketException {
383 DatagramSocketImpl impl;
384 DatagramSocketImplFactory factory = DatagramSocket.factory;
385 if (factory != null) {
386 impl = factory.createDatagramSocketImpl();
387 } else {
388 impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(multicast);
389 }
390 // creates a udp socket
391 impl.create();
392 return impl;
393 }
394
395 /**
396 * Return the {@code DatagramSocketImpl} attached to this socket.
397 *
398 * @return the {@code DatagramSocketImpl} attached to that
399 * DatagramSocket
400 * @throws SocketException never thrown
401 * @since 1.4
402 */
403 DatagramSocketImpl getImpl() throws SocketException {
404 return impl;
405 }
406
407 /**
408 * Binds this DatagramSocket to a specific address and port.
409 * <p>
410 * If the address is {@code null}, then the system will pick up
411 * an ephemeral port and a valid local address to bind the socket.
412 *
413 * @param addr The address and port to bind to.
414 * @throws SocketException if any error happens during the bind, or if the
415 * socket is already bound.
416 * @throws SecurityException if a security manager exists and its
417 * {@code checkListen} method doesn't allow the operation.
418 * @throws IllegalArgumentException if addr is a SocketAddress subclass
419 * not supported by this socket.
420 * @since 1.4
421 */
422 public synchronized void bind(SocketAddress addr) throws SocketException {
423 if (isClosed())
1308 * Returns the unique {@link java.nio.channels.DatagramChannel} object
1309 * associated with this datagram socket, if any.
1310 *
1311 * <p> A datagram socket will have a channel if, and only if, the channel
1312 * itself was created via the {@link java.nio.channels.DatagramChannel#open
1313 * DatagramChannel.open} method.
1314 *
1315 * @return the datagram channel associated with this datagram socket,
1316 * or {@code null} if this socket was not created for a channel
1317 *
1318 * @since 1.4
1319 * @spec JSR-51
1320 */
1321 public DatagramChannel getChannel() {
1322 return null;
1323 }
1324
1325 /**
1326 * User defined factory for all datagram sockets.
1327 */
1328 private static volatile DatagramSocketImplFactory factory;
1329
1330 /**
1331 * Sets the datagram socket implementation factory for the
1332 * application. The factory can be specified only once.
1333 * <p>
1334 * When an application creates a new datagram socket, the socket
1335 * implementation factory's {@code createDatagramSocketImpl} method is
1336 * called to create the actual datagram socket implementation.
1337 * <p>
1338 * Passing {@code null} to the method is a no-op unless the factory
1339 * was already set.
1340 *
1341 * <p>If there is a security manager, this method first calls
1342 * the security manager's {@code checkSetFactory} method
1343 * to ensure the operation is allowed.
1344 * This could result in a SecurityException.
1345 *
1346 * @param fac the desired factory.
1347 * @throws IOException if an I/O error occurs when setting the
1348 * datagram socket factory.
|