Driver Oracle
Sin Instant Client.
Rust puro. Oracle 12c+.
oracle-tns es una implementacion en Rust puro del protocolo TNS de Oracle. Sin Oracle Instant Client, sin bindings a C, sin bibliotecas compartidas. Un binario estatico musl que habla TNS nativamente — O3LOGON, O5LOGON, queries, PL/SQL, procedimientos almacenados, REF CURSORs.
■Este driver conecta a Oracle 12c R1 con verificadores de contrasena 10G/11G — algo que python-oracledb, node-oracledb, oracle-nio y kalliope no pueden hacer (DPY-3015).
~5.5 MB
binario estatico musl
13ms
latencia promedio VPN
5
targets de fuzzing
48M+
ejecuciones de fuzz
Inicio Rapido
Conectar a Oracle
en tres pasos.
1. Agregar dependencia
cargo add oracle-tns2. Configurar conexion
use oracle_tns::{ConnectConfig, OracleSession};
let config = ConnectConfig {
host: "db.example.com".to_string(),
port: 1521,
service_name: "MYDB".to_string(),
username: "myuser".to_string(),
password: "mypassword".to_string(),
};3. Consultar
let mut session = OracleSession::connect(&config).await?;
let rows = session.query(
"SELECT id, name, email FROM users WHERE department = :1",
&[BindParam::varchar("Engineering")],
).await?;
for row in rows {
let id: i64 = row.get("ID")?;
let name: String = row.get("NAME")?;
println!("{id}: {name}");
}
session.close().await?;Funcionalidades
Protocolo Oracle completo
en Rust puro.
| Connect | Handshake TNS, autenticacion O3LOGON (0x939) + O5LOGON, resolucion de service name |
| Query | SELECT con decodificacion completa — VARCHAR2, NUMBER, DATE, RAW, NULL |
| Bind parameters | Variables de bind posicionales (:1, :2) — tipos VARCHAR, INTEGER |
| Paginacion | Soporte OFFSET/FETCH NEXT para limitacion de filas en Oracle 12c+ |
| Bloques PL/SQL | Ejecucion de bloques PL/SQL anonimos con variables de bind |
| Procedimientos | CALL con parametros IN y OUT |
| Parametros OUT | Lectura de valores de salida de llamadas a procedimientos |
| REF CURSOR | Bind de cursor OUT, fetch de result set con metadata de columnas |
| DML | INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE |
| Connection pool | Pool asincrono con conexiones min/max configurables y timeout de inactividad |
| Ping | Verificacion ligera de salud de conexion sobre TNS |
Comparacion
oracle-tns vs el resto
| oracle-tns | python-oracledb | node-oracledb | Instant Client | |
| Tamano binario | ~5.5 MB (static musl) | ~50 MB + Python | ~30 MB + Node.js | ~250 MB |
| Requiere Instant Client | No | Thin: No, Thick: Si | Thin: No, Thick: Si | Si (lo es) |
| Soporte Oracle 12c R1 | Si | Falla (DPY-3015) | Falla | Si |
| Verificador 10G/11G | Si (O3LOGON) | No | No | Si |
| Asincrono | Si (tokio) | Si (asyncio) | Si (promises) | No |
| Connection pooling | Si | Si | Si | Si (OCI) |
| Fuzz testing | Si (48M+ ejecuciones) | No | No | No |
Seguridad
Fuzz-tested.
48 millones de ejecuciones.
Cada parser en oracle-tns esta fuzz-tested con cargo-fuzz. Cinco targets cubriendo decodificacion de paquetes TNS, parsing de numeros, decodificacion de fechas, operaciones de codec y manejo de paquetes de conexion. Cinco bugs encontrados y corregidos antes de llegar a produccion.
| Bug | Target | Impacto | Estado |
| decode_number overflow | fuzz_number | Panic con bytes NUMBER malformados | Corregido |
| AcceptPacket bounds | fuzz_tns_packet | Lectura fuera de limites en paquete truncado | Corregido |
| codec OOM | fuzz_codec | Bomba de asignacion via prefijo de longitud (vector DoS) | Corregido |
| decode_date overflow | fuzz_date | Panic con componentes de fecha invalidos | Corregido |
| slice index panic | fuzz_codec | Indice fuera de limites en chunk CLR parcial | Corregido |
5
targets de fuzz
48M+
ejecuciones totales
5
bugs encontrados
0
issues abiertos
Protocolo Wire
TNS desde el cable.
TNS Packet Framing
Cada mensaje Oracle se envuelve en un paquete TNS: header de 8 bytes con longitud, checksum, tipo y flags. Los tipos incluyen Connect (1), Accept (2), Data (6), Marker (12). El driver maneja reensamblado de paquetes, negociacion SDU y lecturas chunked.
Enteros de Longitud Variable
Oracle usa enteros sin signo UB2 (2 bytes) y UB4 (4 bytes) en formato big-endian para longitudes y offsets. El driver lee estos del cable y los usa para parsear limites de campos en paquetes de datos.
CLR Chunked Encoding
Los datos de columna se codifican en formato CLR (Column Length Representation): un byte de longitud seguido de bytes de datos. Para valores mayores a 254 bytes, se usa codificacion chunked con prefijo 0xFE y multiples segmentos con prefijo de longitud.
Autenticacion O3LOGON / O5LOGON
O5LOGON usa intercambio de claves Diffie-Hellman con SHA-1. O3LOGON (verificador 0x939) es requerido para Oracle 12c R1 con verificadores legacy 10G/11G — esta es la autenticacion que todos los otros thin drivers fallan en implementar.
Referencia API
Tipos y funciones principales.
ConnectConfig
pub struct ConnectConfig {
pub host: String,
pub port: u16,
pub service_name: String,
pub username: String,
pub password: String,
}OracleSession
impl OracleSession {
pub async fn connect(config: &ConnectConfig) -> Result<Self>;
pub async fn query(&mut self, sql: &str, params: &[BindParam]) -> Result<Vec<Row>>;
pub async fn execute(&mut self, sql: &str, params: &[BindParam]) -> Result<u64>;
pub async fn call(&mut self, sql: &str, params: &mut [BindParam]) -> Result<()>;
pub async fn ping(&mut self) -> Result<()>;
pub async fn close(self) -> Result<()>;
}BindParam
impl BindParam {
pub fn varchar(value: &str) -> Self;
pub fn integer(value: i64) -> Self;
pub fn out_varchar() -> Self;
pub fn out_cursor() -> Self;
}Cursor + OracleValue
impl Cursor {
pub fn fetch_all(&self) -> &[Row];
pub fn columns(&self) -> &[ColumnInfo];
}
pub enum OracleValue {
Varchar(String),
Number(f64),
Integer(i64),
Date(NaiveDateTime),
Raw(Vec<u8>),
Null,
}Limitaciones Conocidas
Pendiente de implementar.
☐
Streaming CLOB/BLOB
Los tipos de objetos grandes aun no estan soportados. Valores que excedan el tamano SDU necesitaran lecturas por streaming — implementacion pendiente.
☐
TIMESTAMP WITH TIME ZONE
DATE y TIMESTAMP basicos funcionan. El parsing de TIMESTAMP WITH TIME ZONE y TIMESTAMP WITH LOCAL TIME ZONE aun no esta implementado.
☐
TCP keepalive
Conexiones de larga duracion sobre redes inestables pueden caer silenciosamente. Configuracion de TCP keepalive esta pendiente.