1e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera/* 2e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 5e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * This code is free software; you can redistribute it and/or modify it 6e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * under the terms of the GNU General Public License version 2 only, as 7e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * published by the Free Software Foundation. Oracle designates this 8e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * particular file as subject to the "Classpath" exception as provided 9e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * by Oracle in the LICENSE file that accompanied this code. 10e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 11e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * This code is distributed in the hope that it will be useful, but WITHOUT 12e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * version 2 for more details (a copy is included in the LICENSE file that 15e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * accompanied this code). 16e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 17e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * You should have received a copy of the GNU General Public License version 18e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 2 along with this work; if not, write to the Free Software Foundation, 19e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 21e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * or visit www.oracle.com if you need additional information or have any 23e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * questions. 24e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 25e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 26e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmerapackage sun.nio.ch; 27e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 28e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.nio.channels.*; 29e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.InetAddress; 30e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.net.NetworkInterface; 31e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraimport java.util.*; 32e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 33e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera/** 34e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Simple registry of membership keys for a MulticastChannel. 35e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * 36e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Instances of this object are not safe by multiple concurrent threads. 37e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 38e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 39e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmeraclass MembershipRegistry { 40e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 41e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // map multicast group to keys 42e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private Map<InetAddress,List<MembershipKeyImpl>> groups = null; 43e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 44e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipRegistry() { 45e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 46e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 47e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 48e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Checks registry for membership of the group on the given 49e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * network interface. 50e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 51e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKey checkMembership(InetAddress group, NetworkInterface interf, 52e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetAddress source) 53e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 54e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (groups != null) { 55e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera List<MembershipKeyImpl> keys = groups.get(group); 56e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (keys != null) { 57e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera for (MembershipKeyImpl key: keys) { 58e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (key.networkInterface().equals(interf)) { 59e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // already a member to receive all packets so return 60e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // existing key or detect conflict 61e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source == null) { 62e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (key.sourceAddress() == null) 63e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return key; 64e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalStateException("Already a member to receive all packets"); 65e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 66e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 67e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // already have source-specific membership so return key 68e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // or detect conflict 69e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (key.sourceAddress() == null) 70e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalStateException("Already have source-specific membership"); 71e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source.equals(key.sourceAddress())) 72e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return key; 73e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 74e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 75e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 76e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 77e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return null; 78e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 79e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 80e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 81e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Add membership to the registry, returning a new membership key. 82e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 83e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera void add(MembershipKeyImpl key) { 84e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetAddress group = key.group(); 85e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera List<MembershipKeyImpl> keys; 86e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (groups == null) { 87e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera groups = new HashMap<InetAddress,List<MembershipKeyImpl>>(); 88e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera keys = null; 89e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 90e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera keys = groups.get(group); 91e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 92e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (keys == null) { 93e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera keys = new LinkedList<MembershipKeyImpl>(); 94e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera groups.put(group, keys); 95e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 96e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera keys.add(key); 97e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 98e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 99e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 100e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Remove a key from the registry 101e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 102e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera void remove(MembershipKeyImpl key) { 103e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetAddress group = key.group(); 104e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera List<MembershipKeyImpl> keys = groups.get(group); 105e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (keys != null) { 106e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Iterator<MembershipKeyImpl> i = keys.iterator(); 107e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera while (i.hasNext()) { 108e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (i.next() == key) { 109e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera i.remove(); 110e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera break; 111e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 112e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 113e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (keys.isEmpty()) { 114e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera groups.remove(group); 115e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 116e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 117e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 118e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 119e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 120e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Invalidate all keys in the registry 121e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 122e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera void invalidateAll() { 123e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (groups != null) { 124e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera for (InetAddress group: groups.keySet()) { 125e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera for (MembershipKeyImpl key: groups.get(group)) { 126e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera key.invalidate(); 127e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 128e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 129e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 130e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 131e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera} 132