View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.handler.ipfilter;
    17
    18  import java.net.InetAddress;
    19  import java.net.InetSocketAddress;
    20  import java.util.concurrent.ConcurrentHashMap;
    21  import java.util.concurrent.ConcurrentMap;
    22
    23  import org.jboss.netty.channel.ChannelEvent;
    24  import org.jboss.netty.channel.ChannelHandler.Sharable;
    25  import org.jboss.netty.channel.ChannelHandlerContext;
    26  import org.jboss.netty.channel.ChannelState;
    27  import org.jboss.netty.channel.ChannelStateEvent;
    28
    29  /**
    30   * Handler that block any new connection if there are already a currently active
    31   * channel connected with the same InetAddress (IP).<br>
    32   * <br>
    33   * <p/>
    34   * Take care to not change isBlocked method except if you know what you are doing
    35   * since it is used to test if the current closed connection is to be removed
    36   * or not from the map of currently connected channel.
    37   */
    38  @Sharable
    39  public class OneIpFilterHandler extends IpFilteringHandlerImpl {
    40      /** HashMap of current remote connected InetAddress */
    41      private final ConcurrentMap<InetAddress, Boolean> connectedSet = new ConcurrentHashMap<InetAddress, Boolean>();
    42
    43      @Override
    44      protected boolean accept(ChannelHandlerContext ctx, ChannelEvent e, InetSocketAddress inetSocketAddress)
    45              throws Exception {
    46          InetAddress inetAddress = inetSocketAddress.getAddress();
    47          if (connectedSet.containsKey(inetAddress)) {
    48              return false;
    49          }
    50          connectedSet.put(inetAddress, Boolean.TRUE);
    51          return true;
    52      }
    53
    54      @Override
    55      public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
    56          super.handleUpstream(ctx, e);
    57          // Try to remove entry from Map if already exists
    58          if (e instanceof ChannelStateEvent) {
    59              ChannelStateEvent evt = (ChannelStateEvent) e;
    60              if (evt.getState() == ChannelState.CONNECTED) {
    61                  if (evt.getValue() == null) {
    62                      // DISCONNECTED but was this channel blocked or not
    63                      if (isBlocked(ctx)) {
    64                          // remove inetsocketaddress from set since this channel was not blocked before
    65                          InetSocketAddress inetSocketAddress = (InetSocketAddress) e.getChannel().getRemoteAddress();
    66                          connectedSet.remove(inetSocketAddress.getAddress());
    67                      }
    68                  }
    69              }
    70          }
    71      }
    72
    73  }