Path: blob/master/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java
41159 views
/*1* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.ch;2627import java.net.InetAddress;28import java.net.NetworkInterface;29import java.io.IOException;30import java.nio.channels.MembershipKey;31import java.nio.channels.MulticastChannel;32import java.util.HashSet;3334/**35* MembershipKey implementation.36*/3738class MembershipKeyImpl39extends MembershipKey40{41private final MulticastChannel ch;42private final InetAddress group;43private final NetworkInterface interf;44private final InetAddress source;4546private volatile boolean invalid;4748// lock used when creating or accessing blockedSet49private final Object stateLock = new Object();5051// set of source addresses that are blocked52private HashSet<InetAddress> blockedSet;5354private MembershipKeyImpl(MulticastChannel ch,55InetAddress group,56NetworkInterface interf,57InetAddress source)58{59this.ch = ch;60this.group = group;61this.interf = interf;62this.source = source;63}6465/**66* MembershipKey will additional context for IPv4 membership67*/68static class Type4 extends MembershipKeyImpl {69private final int groupAddress;70private final int interfAddress;71private final int sourceAddress;7273Type4(MulticastChannel ch,74InetAddress group,75NetworkInterface interf,76InetAddress source,77int groupAddress,78int interfAddress,79int sourceAddress)80{81super(ch, group, interf, source);82this.groupAddress = groupAddress;83this.interfAddress = interfAddress;84this.sourceAddress = sourceAddress;85}8687int groupAddress() {88return groupAddress;89}9091int interfaceAddress() {92return interfAddress;93}9495int source() {96return sourceAddress;97}98}99100/**101* MembershipKey will additional context for IPv6 membership102*/103static class Type6 extends MembershipKeyImpl {104private final byte[] groupAddress;105private final int index;106private final byte[] sourceAddress;107108Type6(MulticastChannel ch,109InetAddress group,110NetworkInterface interf,111InetAddress source,112byte[] groupAddress,113int index,114byte[] sourceAddress)115{116super(ch, group, interf, source);117this.groupAddress = groupAddress;118this.index = index;119this.sourceAddress = sourceAddress;120}121122byte[] groupAddress() {123return groupAddress;124}125126int index() {127return index;128}129130byte[] source() {131return sourceAddress;132}133}134135public boolean isValid() {136return !invalid;137}138139// package-private140void invalidate() {141invalid = true;142}143144public void drop() {145// delegate to channel146((DatagramChannelImpl)ch).drop(this);147}148149@Override150public MulticastChannel channel() {151return ch;152}153154@Override155public InetAddress group() {156return group;157}158159@Override160public NetworkInterface networkInterface() {161return interf;162}163164@Override165public InetAddress sourceAddress() {166return source;167}168169@Override170public MembershipKey block(InetAddress toBlock)171throws IOException172{173if (source != null)174throw new IllegalStateException("key is source-specific");175176synchronized (stateLock) {177if ((blockedSet != null) && blockedSet.contains(toBlock)) {178// already blocked, nothing to do179return this;180}181182((DatagramChannelImpl)ch).block(this, toBlock);183184// created blocked set if required and add source address185if (blockedSet == null)186blockedSet = new HashSet<>();187blockedSet.add(toBlock);188}189return this;190}191192@Override193public MembershipKey unblock(InetAddress toUnblock) {194synchronized (stateLock) {195if ((blockedSet == null) || !blockedSet.contains(toUnblock))196throw new IllegalStateException("not blocked");197198((DatagramChannelImpl)ch).unblock(this, toUnblock);199200blockedSet.remove(toUnblock);201}202return this;203}204205@Override206public String toString() {207StringBuilder sb = new StringBuilder(64);208sb.append('<');209sb.append(group.getHostAddress());210sb.append(',');211sb.append(interf.getName());212if (source != null) {213sb.append(',');214sb.append(source.getHostAddress());215}216sb.append('>');217return sb.toString();218}219}220221222