/**
   * 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);
      }
    }
  }
Example #3
0
  /**
   * 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
Example #5
0
  /**
   * 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);
 }