예제 #1
0
 /**
  * Resets the socket timeout to the configured socketTimeout. Does nothing if currently not
  * connected.
  *
  * @throws SQLException If the timeout value cannot be changed
  */
 public final void resetSocketTimeout() throws SQLException {
   if (isConnected()) {
     try {
       final int soTimeout = attachProperties.getSoTimeout();
       final int desiredTimeout = soTimeout != -1 ? soTimeout : 0;
       if (socket.getSoTimeout() != desiredTimeout) {
         socket.setSoTimeout(desiredTimeout);
       }
     } catch (SocketException e) {
       // TODO Add SQLState
       throw new SQLException("Unable to change socket timeout (SO_TIMEOUT)", e);
     }
   }
 }
예제 #2
0
  /**
   * Closes the TCP/IP connection. This is not a normal detach operation.
   *
   * @throws IOException if closing fails
   */
  public final void close() throws IOException {
    IOException ioex = null;
    try {
      if (socket != null) {
        try {
          if (xdrOut != null) xdrOut.close();
        } catch (IOException ex) {
          ioex = ex;
        }

        try {
          if (xdrIn != null) xdrIn.close();
        } catch (IOException ex) {
          if (ioex == null) ioex = ex;
        }

        try {
          socket.close();
        } catch (IOException ex) {
          if (ioex == null) ioex = ex;
        }

        if (ioex != null) throw ioex;
      }
    } finally {
      xdrOut = null;
      xdrIn = null;
      socket = null;
      protocols = null;
    }
  }
예제 #3
0
  /**
   * Establishes the TCP/IP connection to serverName and portNumber of this Connection
   *
   * @throws SQLTimeoutException If the connection cannot be established within the connect timeout
   *     (either explicitly set or implied by the OS timeout of the socket)
   * @throws SQLException If the connection cannot be established.
   */
  public final void socketConnect() throws SQLException {
    try {
      socket = new Socket();
      socket.setTcpNoDelay(true);
      final int connectTimeout = attachProperties.getConnectTimeout();
      final int socketConnectTimeout;
      if (connectTimeout != -1) {
        // connectTimeout is in seconds, need milliseconds
        socketConnectTimeout = (int) TimeUnit.SECONDS.toMillis(connectTimeout);
        // Blocking timeout initially identical to connect timeout
        socket.setSoTimeout(socketConnectTimeout);
      } else {
        // socket connect timeout is not set, so indefinite (0)
        socketConnectTimeout = 0;
        // Blocking timeout to normal socket timeout, 0 if not set
        socket.setSoTimeout(Math.max(attachProperties.getSoTimeout(), 0));
      }

      final int socketBufferSize = attachProperties.getSocketBufferSize();
      if (socketBufferSize != IConnectionProperties.DEFAULT_SOCKET_BUFFER_SIZE) {
        socket.setReceiveBufferSize(socketBufferSize);
        socket.setSendBufferSize(socketBufferSize);
      }

      socket.connect(new InetSocketAddress(getServerName(), getPortNumber()), socketConnectTimeout);
    } catch (SocketTimeoutException ste) {
      throw new FbExceptionBuilder()
          .timeoutException(ISCConstants.isc_network_error)
          .messageParameter(getServerName())
          .cause(ste)
          .toSQLException();
    } catch (IOException ioex) {
      throw new FbExceptionBuilder()
          .exception(ISCConstants.isc_network_error)
          .messageParameter(getServerName())
          .cause(ioex)
          .toSQLException();
    }
  }
예제 #4
0
 /**
  * Writes directly to the {@code OutputStream} of the underlying socket.
  *
  * @param data Data to write
  * @throws IOException If there is no socket, the socket is closed, or for errors writing to the
  *     socket.
  */
 public final void writeDirect(byte[] data) throws IOException {
   if (!isConnected()) throw new SocketException("Socket closed");
   final OutputStream outputStream = socket.getOutputStream();
   outputStream.write(data);
   outputStream.flush();
 }
예제 #5
0
  /**
   * Performs the connection identification phase of the Wire protocol and returns the
   * FbWireDatabase implementation for the agreed protocol.
   *
   * @return FbWireDatabase
   * @throws SQLTimeoutException
   * @throws SQLException
   */
  @Override
  public final C identify() throws SQLException {
    try {
      xdrIn = new XdrInputStream(socket.getInputStream());
      xdrOut = new XdrOutputStream(socket.getOutputStream());

      // Here we identify the user to the engine.
      // This may or may not be used as login info to a database.
      final byte[] userBytes = getSystemUserName().getBytes();
      final byte[] hostBytes = getSystemHostName().getBytes();

      ByteArrayOutputStream userId = new ByteArrayOutputStream();
      userId.write(CNCT_user);
      int userLength = Math.min(userBytes.length, 255);
      userId.write(userLength);
      userId.write(userBytes, 0, userLength);

      userId.write(CNCT_host);
      int hostLength = Math.min(hostBytes.length, 255);
      userId.write(hostLength);
      userId.write(hostBytes, 0, hostLength);
      userId.write(CNCT_user_verification);
      userId.write(0);

      xdrOut.writeInt(op_connect);
      xdrOut.writeInt(op_attach);
      xdrOut.writeInt(CONNECT_VERSION2);
      xdrOut.writeInt(arch_generic);

      xdrOut.writeString(getAttachObjectName(), getEncoding());
      xdrOut.writeInt(protocols.getProtocolCount()); // Count of protocols understood
      xdrOut.writeBuffer(userId.toByteArray());

      for (ProtocolDescriptor protocol : protocols) {
        xdrOut.writeInt(protocol.getVersion()); // Protocol version
        xdrOut.writeInt(protocol.getArchitecture()); // Architecture of client
        xdrOut.writeInt(protocol.getMinimumType()); // Minimum type
        xdrOut.writeInt(protocol.getMaximumType()); // Maximum type
        xdrOut.writeInt(protocol.getWeight()); // Preference weight
      }

      xdrOut.flush();

      if (readNextOperation() == op_accept) {
        protocolVersion = xdrIn.readInt(); // Protocol version
        protocolArchitecture = xdrIn.readInt(); // Architecture for protocol
        protocolMinimumType = xdrIn.readInt(); // Minimum type
        if (protocolVersion < 0) {
          protocolVersion = (protocolVersion & FB_PROTOCOL_MASK) | FB_PROTOCOL_FLAG;
        }

        ProtocolDescriptor descriptor = protocols.getProtocolDescriptor(protocolVersion);
        if (descriptor == null) {
          throw new SQLException(
              String.format(
                  "Unsupported or unexpected protocol version %d connecting to database %s. Supported version(s): %s",
                  protocolVersion, getServerName(), protocols.getProtocolVersions()));
        }
        return createConnectionHandle(descriptor);
      } else {
        try {
          close();
        } catch (Exception ex) {
          log.debug("Ignoring exception on disconnect in connect phase of protocol", ex);
        }
        throw new FbExceptionBuilder().exception(ISCConstants.isc_connect_reject).toSQLException();
      }
    } catch (SocketTimeoutException ste) {
      throw new FbExceptionBuilder()
          .timeoutException(ISCConstants.isc_network_error)
          .messageParameter(getServerName())
          .cause(ste)
          .toSQLException();
    } catch (IOException ioex) {
      throw new FbExceptionBuilder()
          .exception(ISCConstants.isc_network_error)
          .messageParameter(getServerName())
          .cause(ioex)
          .toSQLException();
    }
  }
예제 #6
0
 public final boolean isConnected() {
   return !(socket == null || socket.isClosed());
 }