예제 #1
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;
    }
  }
예제 #2
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();
    }
  }