# IBM JDBC Driver — Wire Protocol Class Index > **Phase 0 spike artifact.** Reverse-lookup index into the decompiled IBM Informix JDBC driver. This document tells us which Java class to read when we want to understand how the JDBC driver implements a given wire-protocol concern. > > **Legal note**: the decompiled source lives in `build/jdbc-src/` and is **not committed to this repository**. It is consulted as a clean-room understanding reference only. The Python implementation in `src/informix_db/` is written from `PROTOCOL_NOTES.md` (which cites both the observed packet bytes and the JDBC class+method that emits them), never copied from the Java source. --- ## JAR identity | Field | Value | |-------|-------| | Source | `/home/rpm/bingham/rtmt/lib/ifxjdbc.jar` (user-provided; an IBM tooling/RTMT install) | | Working copy | `build/ifxjdbc.jar` | | SHA256 | `dc5622cb4e95678d15836b684b6ef1783d37bc0cdd2725208577fc300df4e5f1` | | `Implementation-Title` | `Informix JDBC Driver` | | `Implementation-Version` | `4.50.10-SNAPSHOT` | | `Build-Date` | `2023-03-07T11:30:44-0600` | | `Build-Number` | `146` | | `Main-Class` | `com.informix.jdbc.Version` (printable: "IBM Informix JDBC Driver Version 4.50.JC10") | | Total entries | 685 (.class files) | | Decompiled .java files | 478 | ## Decompilation ```bash java -jar build/tools/cfr.jar build/ifxjdbc.jar --outputdir build/jdbc-src/ --silent ``` CFR version: 0.152 (May 2024). Downloaded from https://github.com/leibnitz27/cfr/releases/download/0.152/cfr-0.152.jar. --- ## Top-level package layout ``` com.informix.asf # wire-transport layer (sockets, framing primitives, SSL, HTTP-tunnel) com.informix.jdbc # JDBC API surface: Driver, Connection, Statement, ResultSet, type wrappers com.informix.jdbc.types # JDBC type-wrapper sub-types com.informix.jdbc.udt # User-defined type support com.informix.jdbcx # XA / DataSource / ConnectionPool extensions com.informix.jns # Java Naming Service (sqlhosts lookup) com.informix.judr # Java User-Defined Routines com.informix.lang # Encoding/decoding bridge between Java types and Informix wire types com.informix.smartTrigger # Smart-trigger event subscription com.informix.types # Informix-side type system (Interval, Decimal, etc.) com.informix.util # Tracing, error messages, properties org.bson.* # MongoDB BSON support — ignore for SQLI work ``` **For SQLI wire-protocol implementation, only `com.informix.asf`, `com.informix.jdbc` (selected files), `com.informix.lang`, and `com.informix.util.IfxErrMsg` matter.** Everything else is JDBC API surface, ORM helpers, or unrelated bundles. --- ## Class index — wire-protocol concern → class ### Wire transport (the layer we're rebuilding in `_socket.py` + `_protocol.py`) | Concern | Class | Path | Notes | |---------|-------|------|-------| | Raw socket lifecycle, SSL, login orchestration | `com.informix.asf.Connection` | `build/jdbc-src/com/informix/asf/Connection.java` (1228 LOC) | The wire-level connection. Owns `Socket asfSocket`, the buffered streams, `IfxDataInputStream/OutputStream`. This is what our `connections.py` layer maps to (just the socket+framing parts; SQL state lives a layer up). | | Wire write primitives | `com.informix.asf.IfxDataOutputStream` | `…/asf/IfxDataOutputStream.java` (205 LOC) | `writeShort`, `writeInt`, `writeChar`, `writeDate`, `writeDateTime`, `writeDecimal`, `writeReal`, `writeDouble`, `writeSmallInt`, `writeLongInt`, `writeLongBigint`, `writePadded` (16-bit alignment). | | Wire read primitives | `com.informix.asf.IfxDataInputStream` | `…/asf/IfxDataInputStream.java` (235 LOC) | Mirror of the above: `readShort`, `readInt`, `readChar` (length-prefixed string), `readDate`, `readDateTime`, `readDecimal`, `readReal`, `readDouble`, `readSmallInt`, `readLongInt`, `readLongBigint`, `readPadded`. | | Protocol tracing (logging hook) | `com.informix.asf.SqliDbg` | `…/asf/SqliDbg.java` (135 LOC) | Records C2S / S2C transitions. Worth reading to learn which fields IBM thinks are interesting enough to log. | | Debug-instrumented streams | `com.informix.asf.IfxDebugDataInputStream` / `OutputStream` | `…/asf/IfxDebug*.java` | Subclasses of the regular streams that emit trace records. Used when `SQLITRACEFILE` opt-prop is set. | | HTTP-tunneled SQLI | `com.informix.asf.HttpConnection`, `HttpBufferedInputStream`, `HttpBufferedOutputStream` | `…/asf/Http*.java` | SQLI-over-HTTP for proxy/firewall traversal. **Phase 6+ at the earliest. Skip for MVP.** | ### Type encoding/decoding (JavaToIfx ↔ IfxToJava) | Concern | Class | Path | Notes | |---------|-------|------|-------| | Java→wire encoders | `com.informix.lang.JavaToIfxType` | `…/lang/JavaToIfxType.java` | `JavaToIfxInt(int)` → 4-byte BE; `JavaToIfxSmallInt(short)` → 2-byte BE; `JavaToIfxLongBigInt(long)` → 8-byte BE; `JavaToIfxLongInt(long)` → 10-byte legacy variable-numeric (skip MVP); `JavaToIfxChar(String)` length-prefixed; `JavaToIfxDate`, `JavaToIfxDateTime`, `JavaToIfxDecimal`, `JavaToIfxReal`, `JavaToIfxDouble`. | | Wire→Java decoders | `com.informix.lang.IfxToJavaType` | `…/lang/IfxToJavaType.java` | Mirror of the above. | | IDS type metadata / type codes | `com.informix.lang.IfxTypes` | `…/lang/IfxTypes.java` | Constants for the IDS internal type IDs. The other half of the answer to "what's in column descriptors". | | INTERVAL day-fraction / year-month structures | `com.informix.lang.IntervalDF`, `IntervalYM`, `Interval` | `…/lang/Interval*.java` | Phase 6+. | ### SQLI protocol (the layer we're rebuilding in `connections.py` + `cursors.py`) | Concern | Class | Path | Notes | |---------|-------|------|-------| | Protocol contract | `com.informix.jdbc.IfxProtocol` (interface) | `…/jdbc/IfxProtocol.java` (146 LOC) | 50-method interface — read this FIRST to understand the protocol's "vocabulary" without drowning in implementation. Methods include `executeBegin/Commit/Rollback/Savepoint`, `executeVersion`, `executeProtocols`, `handlePAMAuthentication`, `executeOpenDatabase`, `executeCommand`, `executePrepare`, `executeExecute`, `executeFetchBlob`, `executeReadSmBlob`, `executeFastPath`, `handlePrivateServerExchange`. | | SQLI protocol implementation | `com.informix.jdbc.IfxSqli` | `…/jdbc/IfxSqli.java` (6501 LOC) | The concrete `IfxProtocol` impl. Owns `IfxDataInputStream is` / `IfxDataOutputStream os` (inherited from `IfxSqliConnect`). Search for `os.writeShort(...)` to find every message-emit site. | | Connection state machine + login orchestration | `com.informix.jdbc.IfxSqliConnect` | `…/jdbc/IfxSqliConnect.java` (5029 LOC) | Holds the `com.informix.asf.Connection`, owns the high-level connection state. Exposes `IfmxConnection`. | | Message-type tag enumeration | `com.informix.jdbc.IfxMessageTypes` | `…/jdbc/IfxMessageTypes.java` (163 LOC) | All 142+ SQLI message type constants. **Goldmine.** See "Message type tag table" in `PROTOCOL_NOTES.md`. | | JDBC Driver entry point | `com.informix.jdbc.IfxDriver` | `…/jdbc/IfxDriver.java` (584 LOC) | URL parsing, property handling, `Driver.connect()` impl. Useful for understanding what opt-props exist and which ones affect protocol behavior. | | Connection extension interface | `com.informix.jdbc.IfmxConnection` (interface) | `…/jdbc/IfmxConnection.java` | Adds Informix-specific methods to `java.sql.Connection`: UDT info, HDR, `scrubConnection()` for pool reuse, `IFX_USEPUT`, prepared-statement cache. | ### Auth handlers | Concern | Class | Notes | |---------|-------|-------| | Plain-password auth | inline in `Connection.encodeAscBinary()` | Username + password are written into the binary login PDU directly. No separate auth round-trip. **MVP target.** | | Legacy text-mode auth (`-pPASSWORD` argv) | `Connection.EncodeAscString()` | Triggered when `capabilities == 0`. Emits literal `sqlexec USER -pPASSWORD VERSION SERIAL -dDB -fIEEEM ` argv string. Skip MVP. | | PAM challenge/response | `IfmxPAM`, `IfxPAMChallenge`, `IfxPAMResponse`; `IfxSqli.handlePAMAuthentication(String)` | Triggered by server-initiated `SQ_CHALLENGE=129` → client replies with `SQ_RESPONSE=130`. **Phase 6+.** | | Trusted Context | flag in `encodeAscBinary` (option bit `ASF_TRUSTCTXT = 0x4000000` in stmtoptions int) | Phase 6+. | | GSSAPI / Kerberos | not directly visible in `Connection.java`; likely handled via JCE provider plumbing | Phase 6+ if ever. | | **CSM is removed** | `Connection.getOptProperties()` throws `"CSM Encryption is no longer supported"` if `SECURITY` or `CSM` is set | Confirmed dead. Cross off forever. | | SSL / TLS | inline in `Connection.openSocket()` | Wraps `Socket` with `SSLSocket`. Default protocols: TLSv1.3, TLSv1.2, TLSv1.1, TLSv1 (Java 11+). **Phase 6+.** | ### Errors | Concern | Class | Notes | |---------|-------|-------| | Error code → message text | `com.informix.util.IfxErrMsg` | Maps SQLCODE to localized text. Used to construct exceptions and warnings. The `Message` CLI tool (`com.informix.jdbc.Message`) is just a thin wrapper. | | Warning code → message text | `com.informix.util.IfxWarnMsg` | Same, for warnings. | | ASF-level (transport) exceptions | `com.informix.asf.IfxASFException`, `IfxASFRemoteException` | Network / login-rejection errors. Distinct from SQL-level exceptions. | | Tracing | `com.informix.util.Trace`, `TraceFlag` | Used throughout. | ### Stuff to ignore - `com.informix.jdbc.types.*`, `com.informix.jdbc.udt.*` — JDBC API helpers, not protocol - `com.informix.jdbcx.*` — DataSource/XA/Pool wrappers; sit ABOVE the protocol layer - `com.informix.jns.*` — sqlhosts lookup; not relevant when we just connect to `host:port` directly - `com.informix.judr.*` — Java UDR support; not protocol - `com.informix.smartTrigger.*` — event-subscription feature; not MVP - `com.informix.jdbc.IfxBlob`, `IfxClob`, `IfxLob*`, `IfxSmBlob`, `IfxSmartLobOutputStream` — large object support; Phase 6+ - `org.bson.*` — bundled MongoDB BSON; for the JSON/BSON column type. Phase 6+ at best - `com.informix.jdbc.IfxBSONObject`, `IfxJSON`, `IfxImpExp` — BSON/JSON wrappers and import/export utilities --- ## Method-level pointers (specific Java methods → wire effect) > Format: `Class#method() → wire bytes emitted/consumed`. Filled in as we read deeper. ### Connection / login - `com.informix.asf.Connection#openSocket()` → opens the TCP (or SSL) socket to `ipAddr:PortNumber`, sets TCP_NODELAY, optional KEEPALIVE. - `com.informix.asf.Connection#sendConnectionRequest(...)` → emits the binary login PDU (`encodeAscBinary` path) or legacy text login (`EncodeAscString` path). - `com.informix.asf.Connection#encodeAscBinary(...)` → emits the binary login PDU. **See `PROTOCOL_NOTES.md §2 Login Sequence` for the byte-by-byte breakdown.** Markers used: 100, 101, 104, 106, 107, 108, 116, 127. - `com.informix.asf.Connection#EncodeSLheader(o, pfPDUsize, slType, slAttribute, slOptions)` → 6-byte SL header preceding the binary login: `[short totalSize][byte slType][byte slAttribute][short slOptions]`. - `com.informix.asf.Connection#EncodeAscString(...)` → emits the legacy text login: `"sqlexec USER -pPASSWORD VERSION SERIAL -dDB -fIEEEM "`. - `com.informix.asf.Connection#recvConnectionResponse()` → reads `[short length][byte SLType][skipBytes 3][markers 100,101][...]` → dispatches to `DecodeAscBinary` / `DecodeAscString`. - `com.informix.asf.Connection#DecodeAscBinary(in)` → reads server response: VersionNumber, SerialNumber, ApplidName, Cap_1, Cap_2, Cap_3, then a switch on a marker (102=SQ_ASCINITRESP, 103=redirect, 127=SQ_ASCEOT clean). - `com.informix.asf.Connection#disconnectOrderly()` → sends bare `[short SQ_EXIT=56]`, expects server to echo back `[short 56]` or `[short 12=SQ_EOT]`. May receive interleaved `[short 99=SQ_XACTSTAT]` mid-stream. ### Type encoding - `com.informix.lang.JavaToIfxType#JavaToIfxInt(int)` → 4-byte big-endian. - `com.informix.lang.JavaToIfxType#JavaToIfxSmallInt(short)` → 2-byte big-endian. - `com.informix.lang.JavaToIfxType#JavaToIfxLongBigInt(long)` → 8-byte big-endian (BIGINT type). - `com.informix.lang.JavaToIfxType#JavaToIfxChar(String)` → returns `[short length+1][bytes][0x00 nul terminator]`. The `+1` accounts for the trailing nul. - `com.informix.asf.IfxDataOutputStream#writePadded(byte[])` → write bytes, then write a 0x00 byte if length is odd. **The 16-bit-alignment requirement.** ### Disconnect - `com.informix.asf.Connection#disconnectOrderly()` (above) - Bare `[short 56]` is the only message the client emits; bare `[short 56]` or `[short 12]` is the response. No header. --- ## Useful greps ```bash # Find every wire-emit site in IfxSqli.java (writeShort calls reveal message tags being sent) grep -nE 'os\.writeShort\(' build/jdbc-src/com/informix/jdbc/IfxSqli.java # Find every wire-read site grep -nE '\.readShort\(\)' build/jdbc-src/com/informix/jdbc/IfxSqli.java # Find login state-machine logic grep -nE 'executeOpenDatabase|executeVersion|executeProtocols|handlePAM|handlePrivate' build/jdbc-src/com/informix/jdbc/IfxSqli.java # Find type-codec dispatch grep -nE 'switch.*[Cc]olType|case.*IfxTypes\.' build/jdbc-src/com/informix/jdbc/IfxSqli.java # Authentication strings grep -rln 'OBFUSCATE\|PWDOBFUSCATION\|GSS\|KERBEROS' build/jdbc-src/ # SQLSTATE / error mapping grep -rln 'SQLSTATE' build/jdbc-src/ ```