jdk/src/share/classes/sun/nio/ch/MembershipKeyImpl.java
changeset 1152 29d6145d1097
child 2057 3acf8e5e2ca0
equal deleted inserted replaced
1151:4070cecdb99d 1152:29d6145d1097
       
     1 /*
       
     2  * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package sun.nio.ch;
       
    27 
       
    28 import java.nio.channels.*;
       
    29 import java.net.InetAddress;
       
    30 import java.net.NetworkInterface;
       
    31 import java.io.IOException;
       
    32 import java.util.HashSet;
       
    33 
       
    34 /**
       
    35  * MembershipKey implementation.
       
    36  */
       
    37 
       
    38 class MembershipKeyImpl
       
    39     extends MembershipKey
       
    40 {
       
    41     private final MulticastChannel ch;
       
    42     private final InetAddress group;
       
    43     private final NetworkInterface interf;
       
    44     private final InetAddress source;
       
    45 
       
    46     // true when key is valid
       
    47     private volatile boolean valid = true;
       
    48 
       
    49     // lock used when creating or accessing blockedSet
       
    50     private Object stateLock = new Object();
       
    51 
       
    52     // set of source addresses that are blocked
       
    53     private HashSet<InetAddress> blockedSet;
       
    54 
       
    55     private MembershipKeyImpl(MulticastChannel ch,
       
    56                               InetAddress group,
       
    57                               NetworkInterface interf,
       
    58                               InetAddress source)
       
    59     {
       
    60         this.ch = ch;
       
    61         this.group = group;
       
    62         this.interf = interf;
       
    63         this.source = source;
       
    64     }
       
    65 
       
    66     /**
       
    67      * MembershipKey will additional context for IPv4 membership
       
    68      */
       
    69     static class Type4 extends MembershipKeyImpl {
       
    70         private final int groupAddress;
       
    71         private final int interfAddress;
       
    72         private final int sourceAddress;
       
    73 
       
    74         Type4(MulticastChannel ch,
       
    75               InetAddress group,
       
    76               NetworkInterface interf,
       
    77               InetAddress source,
       
    78               int groupAddress,
       
    79               int interfAddress,
       
    80               int sourceAddress)
       
    81         {
       
    82             super(ch, group, interf, source);
       
    83             this.groupAddress = groupAddress;
       
    84             this.interfAddress = interfAddress;
       
    85             this.sourceAddress = sourceAddress;
       
    86         }
       
    87 
       
    88         int group() {
       
    89             return groupAddress;
       
    90         }
       
    91 
       
    92         int interfaceAddress() {
       
    93             return interfAddress;
       
    94         }
       
    95 
       
    96         int source() {
       
    97             return sourceAddress;
       
    98         }
       
    99     }
       
   100 
       
   101     /**
       
   102      * MembershipKey will additional context for IPv6 membership
       
   103      */
       
   104     static class Type6 extends MembershipKeyImpl {
       
   105         private final byte[] groupAddress;
       
   106         private final int index;
       
   107         private final byte[] sourceAddress;
       
   108 
       
   109         Type6(MulticastChannel ch,
       
   110               InetAddress group,
       
   111               NetworkInterface interf,
       
   112               InetAddress source,
       
   113               byte[] groupAddress,
       
   114               int index,
       
   115               byte[] sourceAddress)
       
   116         {
       
   117             super(ch, group, interf, source);
       
   118             this.groupAddress = groupAddress;
       
   119             this.index = index;
       
   120             this.sourceAddress = sourceAddress;
       
   121         }
       
   122 
       
   123         byte[] group() {
       
   124             return groupAddress;
       
   125         }
       
   126 
       
   127         int index() {
       
   128             return index;
       
   129         }
       
   130 
       
   131         byte[] source() {
       
   132             return sourceAddress;
       
   133         }
       
   134     }
       
   135 
       
   136     public boolean isValid() {
       
   137         return valid;
       
   138     }
       
   139 
       
   140     // package-private
       
   141     void invalidate() {
       
   142         valid = false;
       
   143     }
       
   144 
       
   145     public void drop() throws IOException {
       
   146         // delegate to channel
       
   147         ((DatagramChannelImpl)ch).drop(this);
       
   148     }
       
   149 
       
   150     @Override
       
   151     public MulticastChannel getChannel() {
       
   152         return ch;
       
   153     }
       
   154 
       
   155     @Override
       
   156     public InetAddress getGroup() {
       
   157         return group;
       
   158     }
       
   159 
       
   160     @Override
       
   161     public NetworkInterface getNetworkInterface() {
       
   162         return interf;
       
   163     }
       
   164 
       
   165     @Override
       
   166     public InetAddress getSourceAddress() {
       
   167         return source;
       
   168     }
       
   169 
       
   170     @Override
       
   171     public MembershipKey block(InetAddress toBlock)
       
   172         throws IOException
       
   173     {
       
   174         if (source != null)
       
   175             throw new IllegalStateException("key is source-specific");
       
   176 
       
   177         synchronized (stateLock) {
       
   178             if ((blockedSet != null) && blockedSet.contains(toBlock)) {
       
   179                 // already blocked, nothing to do
       
   180                 return this;
       
   181             }
       
   182 
       
   183             ((DatagramChannelImpl)ch).block(this, toBlock);
       
   184 
       
   185             // created blocked set if required and add source address
       
   186             if (blockedSet == null)
       
   187                 blockedSet = new HashSet<InetAddress>();
       
   188             blockedSet.add(toBlock);
       
   189         }
       
   190         return this;
       
   191     }
       
   192 
       
   193     @Override
       
   194     public MembershipKey unblock(InetAddress toUnblock)
       
   195         throws IOException
       
   196     {
       
   197         synchronized (stateLock) {
       
   198             if ((blockedSet == null) || !blockedSet.contains(toUnblock))
       
   199                 throw new IllegalStateException("not blocked");
       
   200 
       
   201             ((DatagramChannelImpl)ch).unblock(this, toUnblock);
       
   202 
       
   203             blockedSet.remove(toUnblock);
       
   204         }
       
   205         return this;
       
   206     }
       
   207 
       
   208     @Override
       
   209     public String toString() {
       
   210         StringBuilder sb = new StringBuilder(64);
       
   211         sb.append('<');
       
   212         sb.append(group.getHostAddress());
       
   213         sb.append(',');
       
   214         sb.append(interf.getName());
       
   215         if (source != null) {
       
   216             sb.append(',');
       
   217             sb.append(source.getHostAddress());
       
   218         }
       
   219         sb.append('>');
       
   220         return sb.toString();
       
   221     }
       
   222 }