Пример #1
0
 /**
  * Reads the next operation code. Skips all {@link
  * org.firebirdsql.gds.impl.wire.WireProtocolConstants#op_dummy} codes received.
  *
  * @return Operation code
  * @throws IOException if an error occurs while reading from the underlying InputStream
  */
 public final int readNextOperation() throws IOException {
   int op;
   do {
     op = xdrIn.readInt();
   } while (op == op_dummy);
   return op;
 }
Пример #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();
    }
  }