private MembershipKey innerJoin(InetAddress group,NetworkInterface interf,InetAddress source) throws IOException {
  if (!group.isMulticastAddress())   throw new IllegalArgumentException("Group not a multicast address");
  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");
  }
  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();
    if (registry == null) {
      registry=new MembershipRegistry();
    }
 else {
      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");
      byte[] groupAddress=Net.inet6AsByteArray(group);
      byte[] sourceAddress=(source == null) ? null : Net.inet6AsByteArray(source);
      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 {
      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);
      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;
  }
}

private MembershipKey innerJoin ( InetAddress group , NetworkInterface interf , InetAddress source ) throws IOException { if ( ! group . isMulticastAddress ( ) ) throw new IllegalArgumentException ( "Group not a multicast address" ) ; 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" ) ; } 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 ( ) ; if ( registry == null ) { registry = new MembershipRegistry ( ) ; } else { 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" ) ; byte [ ] groupAddress = Net . inet6AsByteArray ( group ) ; byte [ ] sourceAddress = ( source == null ) ? null : Net . inet6AsByteArray ( source ) ; 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 { 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 ) ; 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 ; } }
joins channel ' s socket to the given group / interface and optional source address .
