/** * Joins a multicast group. Its behavior may be affected by {@code setInterface} or {@code * setNetworkInterface}. * * <p>If there is a security manager, this method first calls its {@code checkMulticast} method * with the {@code mcastaddr} argument as its argument. * * @param mcastaddr is the multicast address to join * @exception IOException if there is an error joining or when the address is not a multicast * address. * @exception SecurityException if a security manager exists and its {@code checkMulticast} method * doesn't allow the join. * @see SecurityManager#checkMulticast(InetAddress) */ public void joinGroup(InetAddress mcastaddr) throws IOException { if (isClosed()) { throw new SocketException("Socket is closed"); } checkAddress(mcastaddr, "joinGroup"); SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(mcastaddr); } if (!mcastaddr.isMulticastAddress()) { throw new SocketException("Not a multicast address"); } /** * required for some platforms where it's not possible to join a group without setting the * interface first. */ NetworkInterface defaultInterface = NetworkInterface.getDefault(); if (!interfaceSet && defaultInterface != null) { setNetworkInterface(defaultInterface); } getImpl().join(mcastaddr); }
public int send(ByteBuffer src, SocketAddress target) throws IOException { if (src == null) throw new NullPointerException(); synchronized (writeLock) { ensureOpen(); InetSocketAddress isa = Net.checkAddress(target); InetAddress ia = isa.getAddress(); if (ia == null) throw new IOException("Target address not resolved"); synchronized (stateLock) { if (!isConnected()) { if (target == null) throw new NullPointerException(); SecurityManager sm = System.getSecurityManager(); if (sm != null) { if (ia.isMulticastAddress()) { sm.checkMulticast(ia); } else { sm.checkConnect(ia.getHostAddress(), isa.getPort()); } } } else { // Connected case; Check address then write if (!target.equals(remoteAddress)) { throw new IllegalArgumentException("Connected address not equal to target address"); } return write(src); } } int n = 0; try { begin(); if (!isOpen()) return 0; writerThread = NativeThread.current(); do { n = send(fd, src, isa); } while ((n == IOStatus.INTERRUPTED) && isOpen()); synchronized (stateLock) { if (isOpen() && (localAddress == null)) { localAddress = Net.localAddress(fd); } } return IOStatus.normalize(n); } finally { writerThread = 0; end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } } }
/** * Leave a multicast group. Its behavior may be affected by <code>setInterface</code> or <code> * setNetworkInterface</code>. * * <p>If there is a security manager, this method first calls its <code>checkMulticast</code> * method with the <code>mcastaddr</code> argument as its argument. * * @param mcastaddr is the multicast address to leave * @exception IOException if there is an error leaving or when the address is not a multicast * address. * @exception SecurityException if a security manager exists and its <code>checkMulticast</code> * method doesn't allow the operation. * @see SecurityManager#checkMulticast(InetAddress) */ public void leaveGroup(InetAddress mcastaddr) throws IOException { if (isClosed()) { throw new SocketException("Socket is closed"); } SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(mcastaddr); } if (!mcastaddr.isMulticastAddress()) { throw new SocketException("Not a multicast address"); } getImpl().leave(mcastaddr); }
/** * Sends a datagram packet to the destination, with a TTL (time- to-live) other than the default * for the socket. This method need only be used in instances where a particular TTL is desired; * otherwise it is preferable to set a TTL once on the socket, and use that default TTL for all * packets. This method does <B>not </B> alter the default TTL for the socket. Its behavior may be * affected by {@code setInterface}. * * <p>If there is a security manager, this method first performs some security checks. First, if * {@code p.getAddress().isMulticastAddress()} is true, this method calls the security manager's * {@code checkMulticast} method with {@code p.getAddress()} and {@code ttl} as its arguments. If * the evaluation of that expression is false, this method instead calls the security manager's * {@code checkConnect} method with arguments {@code p.getAddress().getHostAddress()} and {@code * p.getPort()}. Each call to a security manager method could result in a SecurityException if the * operation is not allowed. * * @param p is the packet to be sent. The packet should contain the destination multicast ip * address and the data to be sent. One does not need to be the member of the group to send * packets to a destination multicast address. * @param ttl optional time to live for multicast packet. default ttl is 1. * @exception IOException is raised if an error occurs i.e error while setting ttl. * @exception SecurityException if a security manager exists and its {@code checkMulticast} or * {@code checkConnect} method doesn't allow the send. * @deprecated Use the following code or its equivalent instead: ...... int ttl = * mcastSocket.getTimeToLive(); mcastSocket.setTimeToLive(newttl); mcastSocket.send(p); * mcastSocket.setTimeToLive(ttl); ...... * @see DatagramSocket#send * @see DatagramSocket#receive * @see SecurityManager#checkMulticast(java.net.InetAddress, byte) * @see SecurityManager#checkConnect */ @Deprecated public void send(DatagramPacket p, byte ttl) throws IOException { if (isClosed()) throw new SocketException("Socket is closed"); checkAddress(p.getAddress(), "send"); synchronized (ttlLock) { synchronized (p) { if (connectState == ST_NOT_CONNECTED) { // Security manager makes sure that the multicast address // is allowed one and that the ttl used is less // than the allowed maxttl. SecurityManager security = System.getSecurityManager(); if (security != null) { if (p.getAddress().isMulticastAddress()) { security.checkMulticast(p.getAddress(), ttl); } else { security.checkConnect(p.getAddress().getHostAddress(), p.getPort()); } } } else { // we're connected InetAddress packetAddress = null; packetAddress = p.getAddress(); if (packetAddress == null) { p.setAddress(connectedAddress); p.setPort(connectedPort); } else if ((!packetAddress.equals(connectedAddress)) || p.getPort() != connectedPort) { throw new SecurityException("connected address and packet address" + " differ"); } } byte dttl = getTTL(); try { if (ttl != dttl) { // set the ttl getImpl().setTTL(ttl); } // call the datagram method to send getImpl().send(p); } finally { // set it back to default if (ttl != dttl) { getImpl().setTTL(dttl); } } } // synch p } // synch ttl } // method
/** * Leave a multicast group on a specified local interface. * * <p>If there is a security manager, this method first calls its <code>checkMulticast</code> * method with the <code>mcastaddr</code> argument as its argument. * * @param mcastaddr is the multicast address to leave * @param netIf specifies the local interface or <i>null</i> to defer to the interface set by * {@link MulticastSocket#setInterface(InetAddress)} or {@link * MulticastSocket#setNetworkInterface(NetworkInterface)} * @exception IOException if there is an error leaving or when the address is not a multicast * address. * @exception SecurityException if a security manager exists and its <code>checkMulticast</code> * method doesn't allow the operation. * @throws IllegalArgumentException if mcastaddr is null or is a SocketAddress subclass not * supported by this socket * @see SecurityManager#checkMulticast(InetAddress) * @since 1.4 */ public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException { if (isClosed()) throw new SocketException("Socket is closed"); if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress)) throw new IllegalArgumentException("Unsupported address type"); if (oldImpl) throw new UnsupportedOperationException(); SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(((InetSocketAddress) mcastaddr).getAddress()); } if (!((InetSocketAddress) mcastaddr).getAddress().isMulticastAddress()) { throw new SocketException("Not a multicast address"); } getImpl().leaveGroup(mcastaddr, netIf); }
/** * {@collect.stats} {@description.open} Connects this socket to a remote socket address (IP * address + port number). Binds socket if not already bound. * * <p>{@description.close} * * @param addr The remote address. * @param port The remote port * @throws SocketException if binding the socket fails. */ private synchronized void connectInternal(InetAddress address, int port) throws SocketException { if (port < 0 || port > 0xFFFF) { throw new IllegalArgumentException("connect: " + port); } if (address == null) { throw new IllegalArgumentException("connect: null address"); } checkAddress(address, "connect"); if (isClosed()) return; SecurityManager security = System.getSecurityManager(); if (security != null) { if (address.isMulticastAddress()) { security.checkMulticast(address); } else { security.checkConnect(address.getHostAddress(), port); security.checkAccept(address.getHostAddress(), port); } } if (!isBound()) bind(new InetSocketAddress(0)); // old impls do not support connect/disconnect if (oldImpl) { connectState = ST_CONNECTED_NO_IMPL; } else { try { getImpl().connect(address, port); // socket is now connected by the impl connectState = ST_CONNECTED; } catch (SocketException se) { // connection will be emulated by DatagramSocket connectState = ST_CONNECTED_NO_IMPL; } } connectedAddress = address; connectedPort = port; }
/** * {@collect.stats} {@description.open} Sends a datagram packet from this socket. The <code> * DatagramPacket</code> includes information indicating the data to be sent, its length, the IP * address of the remote host, and the port number on the remote host. * * <p>If there is a security manager, and the socket is not currently connected to a remote * address, this method first performs some security checks. First, if <code> * p.getAddress().isMulticastAddress()</code> is true, this method calls the security manager's * <code>checkMulticast</code> method with <code>p.getAddress()</code> as its argument. If the * evaluation of that expression is false, this method instead calls the security manager's <code> * checkConnect</code> method with arguments <code>p.getAddress().getHostAddress()</code> and * <code>p.getPort()</code>. Each call to a security manager method could result in a * SecurityException if the operation is not allowed. {@description.close} * * @param p the <code>DatagramPacket</code> to be sent. * @exception IOException if an I/O error occurs. * @exception SecurityException if a security manager exists and its <code>checkMulticast</code> * or <code>checkConnect</code> method doesn't allow the send. * @exception PortUnreachableException may be thrown if the socket is connected to a currently * unreachable destination. Note, there is no guarantee that the exception will be thrown. * @exception java.nio.channels.IllegalBlockingModeException if this socket has an associated * channel, and the channel is in non-blocking mode. * @see java.net.DatagramPacket * @see SecurityManager#checkMulticast(InetAddress) * @see SecurityManager#checkConnect * @revised 1.4 * @spec JSR-51 */ public void send(DatagramPacket p) throws IOException { InetAddress packetAddress = null; synchronized (p) { if (isClosed()) throw new SocketException("Socket is closed"); checkAddress(p.getAddress(), "send"); if (connectState == ST_NOT_CONNECTED) { // check the address is ok wiht the security manager on every send. SecurityManager security = System.getSecurityManager(); // The reason you want to synchronize on datagram packet // is because you dont want an applet to change the address // while you are trying to send the packet for example // after the security check but before the send. if (security != null) { if (p.getAddress().isMulticastAddress()) { security.checkMulticast(p.getAddress()); } else { security.checkConnect(p.getAddress().getHostAddress(), p.getPort()); } } } else { // we're connected packetAddress = p.getAddress(); if (packetAddress == null) { p.setAddress(connectedAddress); p.setPort(connectedPort); } else if ((!packetAddress.equals(connectedAddress)) || p.getPort() != connectedPort) { throw new IllegalArgumentException( "connected address " + "and packet address" + " differ"); } } // Check whether the socket is bound if (!isBound()) bind(new InetSocketAddress(0)); // call the method to send getImpl().send(p); } }
/** Joins channel's socket to the given group/interface and optional source address. */ private MembershipKey innerJoin(InetAddress group, NetworkInterface interf, InetAddress source) throws IOException { if (!group.isMulticastAddress()) throw new IllegalArgumentException("Group not a multicast address"); // check multicast address is compatible with this socket if (group instanceof Inet4Address) { if (family == StandardProtocolFamily.INET6 && !Net.canIPv6SocketJoinIPv4Group()) throw new IllegalArgumentException("IPv6 socket cannot join IPv4 multicast group"); } else if (group instanceof Inet6Address) { if (family != StandardProtocolFamily.INET6) throw new IllegalArgumentException("Only IPv6 sockets can join IPv6 multicast group"); } else { throw new IllegalArgumentException("Address type not supported"); } // check source address if (source != null) { if (source.isAnyLocalAddress()) throw new IllegalArgumentException("Source address is a wildcard address"); if (source.isMulticastAddress()) throw new IllegalArgumentException("Source address is multicast address"); if (source.getClass() != group.getClass()) throw new IllegalArgumentException("Source address is different type to group"); } SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkMulticast(group); synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); // check the registry to see if we are already a member of the group if (registry == null) { registry = new MembershipRegistry(); } else { // return existing membership key MembershipKey key = registry.checkMembership(group, interf, source); if (key != null) return key; } MembershipKeyImpl key; if ((family == StandardProtocolFamily.INET6) && ((group instanceof Inet6Address) || Net.canJoin6WithIPv4Group())) { int index = interf.getIndex(); if (index == -1) throw new IOException("Network interface cannot be identified"); // need multicast and source address as byte arrays byte[] groupAddress = Net.inet6AsByteArray(group); byte[] sourceAddress = (source == null) ? null : Net.inet6AsByteArray(source); // join the group int n = Net.join6(fd, groupAddress, index, sourceAddress); if (n == IOStatus.UNAVAILABLE) throw new UnsupportedOperationException(); key = new MembershipKeyImpl.Type6( this, group, interf, source, groupAddress, index, sourceAddress); } else { // need IPv4 address to identify interface Inet4Address target = Net.anyInet4Address(interf); if (target == null) throw new IOException("Network interface not configured for IPv4"); int groupAddress = Net.inet4AsInt(group); int targetAddress = Net.inet4AsInt(target); int sourceAddress = (source == null) ? 0 : Net.inet4AsInt(source); // join the group int n = Net.join4(fd, groupAddress, targetAddress, sourceAddress); if (n == IOStatus.UNAVAILABLE) throw new UnsupportedOperationException(); key = new MembershipKeyImpl.Type4( this, group, interf, source, groupAddress, targetAddress, sourceAddress); } registry.add(key); return key; } }
@SuppressWarnings("deprecation") // we have to override it in case it's used by anyone @Override public void checkMulticast(final InetAddress pMaddr, final byte pTtl) { if (finalSecurityManager != null) finalSecurityManager.checkMulticast(pMaddr, pTtl); }
@Override public void checkMulticast(final InetAddress pMaddr) { if (finalSecurityManager != null) finalSecurityManager.checkMulticast(pMaddr); }
@Override public void checkMulticast(final InetAddress maddr) { if (securityManager != null) securityManager.checkMulticast(maddr); }