View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.transport.socket.nio;
    21
    22  import java.io.IOException;
    23  import java.net.InetAddress;
    24  import java.net.InetSocketAddress;
    25  import java.net.ServerSocket;
    26  import java.net.Socket;
    27  import java.net.SocketException;
    28  import java.net.UnknownHostException;
    29  import java.util.LinkedHashMap;
    30  import java.util.Map;
    31  import java.util.Map.Entry;
    32
    33  import org.apache.mina.common.ExceptionMonitor;
    34  import org.apache.mina.common.IoConnectorConfig;
    35  import org.apache.mina.common.support.BaseIoSessionConfig;
    36
    37  /**
    38   * An {@link IoConnectorConfig} for {@link SocketConnector}.
    39   *
    40   * @author The Apache Directory Project (mina-dev@directory.apache.org)
    41   * @version $Rev: 647053 $, $Date: 2008-04-11 14:40:04 +0900 (Fri, 11 Apr 2008) $
    42   */
    43  public class SocketSessionConfigImpl extends BaseIoSessionConfig implements
    44          SocketSessionConfig {
    45      private static Map<InetSocketAddress, InetAddress> TEST_ADDRESSES = new LinkedHashMap<InetSocketAddress, InetAddress>();
    46
    47      private static boolean SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
    48
    49      private static boolean SET_SEND_BUFFER_SIZE_AVAILABLE = false;
    50
    51      private static boolean GET_TRAFFIC_CLASS_AVAILABLE = false;
    52
    53      private static boolean SET_TRAFFIC_CLASS_AVAILABLE = false;
    54
    55      private static boolean DEFAULT_REUSE_ADDRESS = false;
    56
    57      private static int DEFAULT_RECEIVE_BUFFER_SIZE = 1024;
    58
    59      private static int DEFAULT_SEND_BUFFER_SIZE = 1024;
    60
    61      private static int DEFAULT_TRAFFIC_CLASS = 0;
    62
    63      private static boolean DEFAULT_KEEP_ALIVE = false;
    64
    65      private static boolean DEFAULT_OOB_INLINE = false;
    66
    67      private static int DEFAULT_SO_LINGER = -1;
    68
    69      private static boolean DEFAULT_TCP_NO_DELAY = false;
    70
    71      static {
    72          initializeTestAddresses();
    73
    74          boolean success = false;
    75          for (Entry<InetSocketAddress, InetAddress> e : TEST_ADDRESSES
    76                  .entrySet()) {
    77              success = initializeDefaultSocketParameters(e.getKey(), e
    78                      .getValue());
    79              if (success) {
    80                  break;
    81              }
    82          }
    83
    84          if (!success) {
    85              initializeFallbackDefaultSocketParameters();
    86          }
    87      }
    88
    89      private static void initializeFallbackDefaultSocketParameters() {
    90          Socket unconnectedSocket = new Socket(); // Use a unconnected socket.
    91          try {
    92              initializeDefaultSocketParameters(unconnectedSocket);
    93          } catch (SocketException se) {
    94              ExceptionMonitor.getInstance().exceptionCaught(se);
    95
    96              try {
    97                  unconnectedSocket.close();
    98              } catch (IOException ioe) {
    99                  ExceptionMonitor.getInstance().exceptionCaught(ioe);
    100             }
    101         }
    102     }
    103
    104     private static void initializeTestAddresses() {
    105         try {
    106             // These two tests were disabled due to DIRMINA-560
    107             // (IPv4 localhost TEST_ADDRESS causes server to hang)
    108
    109             // IPv6 localhost
    110             //TEST_ADDRESSES.put(new InetSocketAddress(InetAddress
    111             //        .getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    112             //                0, 0, 0, 0, 1 }), 0), InetAddress
    113             //        .getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    114             //                0, 0, 0, 0, 1 }));
    115
    116             // IPv4 localhost
    117             //TEST_ADDRESSES.put(new InetSocketAddress(InetAddress
    118             //        .getByAddress(new byte[] { 127, 0, 0, 1 }), 0), InetAddress
    119             //        .getByAddress(new byte[] { 127, 0, 0, 1 }));
    120
    121             // Bind to wildcard interface and connect to IPv6 localhost
    122             TEST_ADDRESSES.put(new InetSocketAddress(0), InetAddress
    123                     .getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    124                             0, 0, 0, 0, 1 }));
    125
    126             // Bind to wildcard interface and connect to IPv4 localhost
    127             TEST_ADDRESSES.put(new InetSocketAddress(0), InetAddress
    128                     .getByAddress(new byte[] { 127, 0, 0, 1 }));
    129
    130         } catch (UnknownHostException e) {
    131             ExceptionMonitor.getInstance().exceptionCaught(e);
    132         }
    133     }
    134
    135     private static boolean initializeDefaultSocketParameters(
    136             InetSocketAddress bindAddress, InetAddress connectAddress) {
    137         ServerSocket ss = null;
    138         Socket socket = null;
    139
    140         try {
    141             ss = new ServerSocket();
    142             ss.bind(bindAddress);
    143             socket = new Socket();
    144
    145             // Timeout is set to 10 seconds in case of infinite blocking
    146             // on some platform.
    147             socket.connect(new InetSocketAddress(connectAddress, ss
    148                     .getLocalPort()), 10000);
    149
    150             initializeDefaultSocketParameters(socket);
    151             return true;
    152         } catch (Exception e) {
    153             return false;
    154         } finally {
    155             if (socket != null) {
    156                 try {
    157                     socket.close();
    158                 } catch (IOException e) {
    159                     ExceptionMonitor.getInstance().exceptionCaught(e);
    160                 }
    161             }
    162
    163             if (ss != null) {
    164                 try {
    165                     ss.close();
    166                 } catch (IOException e) {
    167                     ExceptionMonitor.getInstance().exceptionCaught(e);
    168                 }
    169             }
    170         }
    171     }
    172
    173     private static void initializeDefaultSocketParameters(Socket socket)
    174             throws SocketException {
    175         DEFAULT_REUSE_ADDRESS = socket.getReuseAddress();
    176         DEFAULT_RECEIVE_BUFFER_SIZE = socket.getReceiveBufferSize();
    177         DEFAULT_SEND_BUFFER_SIZE = socket.getSendBufferSize();
    178         DEFAULT_KEEP_ALIVE = socket.getKeepAlive();
    179         DEFAULT_OOB_INLINE = socket.getOOBInline();
    180         DEFAULT_SO_LINGER = socket.getSoLinger();
    181         DEFAULT_TCP_NO_DELAY = socket.getTcpNoDelay();
    182
    183         // Check if setReceiveBufferSize is supported.
    184         try {
    185             socket.setReceiveBufferSize(DEFAULT_RECEIVE_BUFFER_SIZE);
    186             SET_RECEIVE_BUFFER_SIZE_AVAILABLE = true;
    187         } catch (SocketException e) {
    188             SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
    189         }
    190
    191         // Check if setSendBufferSize is supported.
    192         try {
    193             socket.setSendBufferSize(DEFAULT_SEND_BUFFER_SIZE);
    194             SET_SEND_BUFFER_SIZE_AVAILABLE = true;
    195         } catch (SocketException e) {
    196             SET_SEND_BUFFER_SIZE_AVAILABLE = false;
    197         }
    198
    199         // Check if getTrafficClass is supported.
    200         try {
    201             DEFAULT_TRAFFIC_CLASS = socket.getTrafficClass();
    202             GET_TRAFFIC_CLASS_AVAILABLE = true;
    203         } catch (SocketException e) {
    204             GET_TRAFFIC_CLASS_AVAILABLE = false;
    205             DEFAULT_TRAFFIC_CLASS = 0;
    206         }
    207     }
    208
    209     public static boolean isSetReceiveBufferSizeAvailable() {
    210         return SET_RECEIVE_BUFFER_SIZE_AVAILABLE;
    211     }
    212
    213     public static boolean isSetSendBufferSizeAvailable() {
    214         return SET_SEND_BUFFER_SIZE_AVAILABLE;
    215     }
    216
    217     public static boolean isGetTrafficClassAvailable() {
    218         return GET_TRAFFIC_CLASS_AVAILABLE;
    219     }
    220
    221     public static boolean isSetTrafficClassAvailable() {
    222         return SET_TRAFFIC_CLASS_AVAILABLE;
    223     }
    224
    225     private boolean reuseAddress = DEFAULT_REUSE_ADDRESS;
    226
    227     private int receiveBufferSize = DEFAULT_RECEIVE_BUFFER_SIZE;
    228
    229     private int sendBufferSize = DEFAULT_SEND_BUFFER_SIZE;
    230
    231     private int trafficClass = DEFAULT_TRAFFIC_CLASS;
    232
    233     private boolean keepAlive = DEFAULT_KEEP_ALIVE;
    234
    235     private boolean oobInline = DEFAULT_OOB_INLINE;
    236
    237     private int soLinger = DEFAULT_SO_LINGER;
    238
    239     private boolean tcpNoDelay = DEFAULT_TCP_NO_DELAY;
    240
    241     /**
    242      * Creates a new instance.
    243      */
    244     public SocketSessionConfigImpl() {
    245     }
    246
    247     public boolean isReuseAddress() {
    248         return reuseAddress;
    249     }
    250
    251     public void setReuseAddress(boolean reuseAddress) {
    252         this.reuseAddress = reuseAddress;
    253     }
    254
    255     public int getReceiveBufferSize() {
    256         return receiveBufferSize;
    257     }
    258
    259     public void setReceiveBufferSize(int receiveBufferSize) {
    260         this.receiveBufferSize = receiveBufferSize;
    261     }
    262
    263     public int getSendBufferSize() {
    264         return sendBufferSize;
    265     }
    266
    267     public void setSendBufferSize(int sendBufferSize) {
    268         this.sendBufferSize = sendBufferSize;
    269     }
    270
    271     public int getTrafficClass() {
    272         return trafficClass;
    273     }
    274
    275     public void setTrafficClass(int trafficClass) {
    276         this.trafficClass = trafficClass;
    277     }
    278
    279     public boolean isKeepAlive() {
    280         return keepAlive;
    281     }
    282
    283     public void setKeepAlive(boolean keepAlive) {
    284         this.keepAlive = keepAlive;
    285     }
    286
    287     public boolean isOobInline() {
    288         return oobInline;
    289     }
    290
    291     public void setOobInline(boolean oobInline) {
    292         this.oobInline = oobInline;
    293     }
    294
    295     public int getSoLinger() {
    296         return soLinger;
    297     }
    298
    299     public void setSoLinger(int soLinger) {
    300         this.soLinger = soLinger;
    301     }
    302
    303     public boolean isTcpNoDelay() {
    304         return tcpNoDelay;
    305     }
    306
    307     public void setTcpNoDelay(boolean tcpNoDelay) {
    308         this.tcpNoDelay = tcpNoDelay;
    309     }
    310 }