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: 575241 $, $Date: 2007-09-13 11:32:59 +0200 (Thu, 13 Sep 2007) $
    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             // IPv6 localhost
    107             TEST_ADDRESSES.put(new InetSocketAddress(InetAddress
    108                     .getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    109                             0, 0, 0, 0, 1 }), 0), InetAddress
    110                     .getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    111                             0, 0, 0, 0, 1 }));
    112
    113             // IPv4 localhost
    114             TEST_ADDRESSES.put(new InetSocketAddress(InetAddress
    115                     .getByAddress(new byte[] { 127, 0, 0, 1 }), 0), InetAddress
    116                     .getByAddress(new byte[] { 127, 0, 0, 1 }));
    117
    118             // Bind to wildcard interface and connect to IPv6 localhost
    119             TEST_ADDRESSES.put(new InetSocketAddress(0), InetAddress
    120                     .getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    121                             0, 0, 0, 0, 1 }));
    122
    123             // Bind to wildcard interface and connect to IPv4 localhost
    124             TEST_ADDRESSES.put(new InetSocketAddress(0), InetAddress
    125                     .getByAddress(new byte[] { 127, 0, 0, 1 }));
    126
    127         } catch (UnknownHostException e) {
    128             ExceptionMonitor.getInstance().exceptionCaught(e);
    129         }
    130     }
    131
    132     private static boolean initializeDefaultSocketParameters(
    133             InetSocketAddress bindAddress, InetAddress connectAddress) {
    134         ServerSocket ss = null;
    135         Socket socket = null;
    136
    137         try {
    138             ss = new ServerSocket();
    139             ss.bind(bindAddress);
    140             socket = new Socket();
    141
    142             // Timeout is set to 10 seconds in case of infinite blocking
    143             // on some platform.
    144             socket.connect(new InetSocketAddress(connectAddress, ss
    145                     .getLocalPort()), 10000);
    146
    147             initializeDefaultSocketParameters(socket);
    148             return true;
    149         } catch (Exception e) {
    150             return false;
    151         } finally {
    152             if (socket != null) {
    153                 try {
    154                     socket.close();
    155                 } catch (IOException e) {
    156                     ExceptionMonitor.getInstance().exceptionCaught(e);
    157                 }
    158             }
    159
    160             if (ss != null) {
    161                 try {
    162                     ss.close();
    163                 } catch (IOException e) {
    164                     ExceptionMonitor.getInstance().exceptionCaught(e);
    165                 }
    166             }
    167         }
    168     }
    169
    170     private static void initializeDefaultSocketParameters(Socket socket)
    171             throws SocketException {
    172         DEFAULT_REUSE_ADDRESS = socket.getReuseAddress();
    173         DEFAULT_RECEIVE_BUFFER_SIZE = socket.getReceiveBufferSize();
    174         DEFAULT_SEND_BUFFER_SIZE = socket.getSendBufferSize();
    175         DEFAULT_KEEP_ALIVE = socket.getKeepAlive();
    176         DEFAULT_OOB_INLINE = socket.getOOBInline();
    177         DEFAULT_SO_LINGER = socket.getSoLinger();
    178         DEFAULT_TCP_NO_DELAY = socket.getTcpNoDelay();
    179
    180         // Check if setReceiveBufferSize is supported.
    181         try {
    182             socket.setReceiveBufferSize(DEFAULT_RECEIVE_BUFFER_SIZE);
    183             SET_RECEIVE_BUFFER_SIZE_AVAILABLE = true;
    184         } catch (SocketException e) {
    185             SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
    186         }
    187
    188         // Check if setSendBufferSize is supported.
    189         try {
    190             socket.setSendBufferSize(DEFAULT_SEND_BUFFER_SIZE);
    191             SET_SEND_BUFFER_SIZE_AVAILABLE = true;
    192         } catch (SocketException e) {
    193             SET_SEND_BUFFER_SIZE_AVAILABLE = false;
    194         }
    195
    196         // Check if getTrafficClass is supported.
    197         try {
    198             DEFAULT_TRAFFIC_CLASS = socket.getTrafficClass();
    199             GET_TRAFFIC_CLASS_AVAILABLE = true;
    200         } catch (SocketException e) {
    201             GET_TRAFFIC_CLASS_AVAILABLE = false;
    202             DEFAULT_TRAFFIC_CLASS = 0;
    203         }
    204     }
    205
    206     public static boolean isSetReceiveBufferSizeAvailable() {
    207         return SET_RECEIVE_BUFFER_SIZE_AVAILABLE;
    208     }
    209
    210     public static boolean isSetSendBufferSizeAvailable() {
    211         return SET_SEND_BUFFER_SIZE_AVAILABLE;
    212     }
    213
    214     public static boolean isGetTrafficClassAvailable() {
    215         return GET_TRAFFIC_CLASS_AVAILABLE;
    216     }
    217
    218     public static boolean isSetTrafficClassAvailable() {
    219         return SET_TRAFFIC_CLASS_AVAILABLE;
    220     }
    221
    222     private boolean reuseAddress = DEFAULT_REUSE_ADDRESS;
    223
    224     private int receiveBufferSize = DEFAULT_RECEIVE_BUFFER_SIZE;
    225
    226     private int sendBufferSize = DEFAULT_SEND_BUFFER_SIZE;
    227
    228     private int trafficClass = DEFAULT_TRAFFIC_CLASS;
    229
    230     private boolean keepAlive = DEFAULT_KEEP_ALIVE;
    231
    232     private boolean oobInline = DEFAULT_OOB_INLINE;
    233
    234     private int soLinger = DEFAULT_SO_LINGER;
    235
    236     private boolean tcpNoDelay = DEFAULT_TCP_NO_DELAY;
    237
    238     /**
    239      * Creates a new instance.
    240      */
    241     public SocketSessionConfigImpl() {
    242     }
    243
    244     public boolean isReuseAddress() {
    245         return reuseAddress;
    246     }
    247
    248     public void setReuseAddress(boolean reuseAddress) {
    249         this.reuseAddress = reuseAddress;
    250     }
    251
    252     public int getReceiveBufferSize() {
    253         return receiveBufferSize;
    254     }
    255
    256     public void setReceiveBufferSize(int receiveBufferSize) {
    257         this.receiveBufferSize = receiveBufferSize;
    258     }
    259
    260     public int getSendBufferSize() {
    261         return sendBufferSize;
    262     }
    263
    264     public void setSendBufferSize(int sendBufferSize) {
    265         this.sendBufferSize = sendBufferSize;
    266     }
    267
    268     public int getTrafficClass() {
    269         return trafficClass;
    270     }
    271
    272     public void setTrafficClass(int trafficClass) {
    273         this.trafficClass = trafficClass;
    274     }
    275
    276     public boolean isKeepAlive() {
    277         return keepAlive;
    278     }
    279
    280     public void setKeepAlive(boolean keepAlive) {
    281         this.keepAlive = keepAlive;
    282     }
    283
    284     public boolean isOobInline() {
    285         return oobInline;
    286     }
    287
    288     public void setOobInline(boolean oobInline) {
    289         this.oobInline = oobInline;
    290     }
    291
    292     public int getSoLinger() {
    293         return soLinger;
    294     }
    295
    296     public void setSoLinger(int soLinger) {
    297         this.soLinger = soLinger;
    298     }
    299
    300     public boolean isTcpNoDelay() {
    301         return tcpNoDelay;
    302     }
    303
    304     public void setTcpNoDelay(boolean tcpNoDelay) {
    305         this.tcpNoDelay = tcpNoDelay;
    306     }
    307 }