feat(renaser): Fase 20 — Akasha Over Ether (grafo distribuido)
Tres mensajes y un EtherType propio bastan para extender el grafo de
objetos —direccionado por contenido, ya BLAKE3— a otras maquinas
renaser que escuchen en la misma red de capa-2. Sin TCP, sin IP,
sin DNS.
Crate nueva 'akasha/' (no_std compartido, gemela de 'formato',
excluida del workspace):
- MensajeAkasha enum con SolicitarObjeto(id), ProveedorObjeto(id,
payload), AnunciarRaiz(id).
- Codec: postcard (mismo que ya usa el grafo en disco).
- EtherType: 0x88B5. MAX_PAYLOAD_AKASHA = 1486 (MTU sin fragmentar).
- Helpers componer_frame(src, dst, msg) y analizar_frame(bytes) que
distinguen EtherType ajeno, frame truncado y payload basura.
- 6 pruebas unitarias en verde.
Modulo nuevo 'kernel/src/akasha.rs' con tres oficios:
1. Demuxer (drenar_y_demultiplexar): drena la cola RX del dispositivo
virtio-net y demultiplexa: frames AoE con payload valido los
procesa el respondedor; el resto va a una cola del userspace que
'sys_net_recibir' ahora lee. Frames 0x88B5 con payload
no-postcard (saludo de pregon) se cuentan y tambien viajan al
userspace.
2. Atencion de mensajes (procesar):
- SolicitarObjeto(id): consulta almacen::recuperar; si tenemos el
objeto, respondemos ProveedorObjeto unicast con objeto.serializar()
y re-hashing de defensa en profundidad.
- ProveedorObjeto(id, payload): verifica blake3(payload)==id antes
de absorber con almacen::almacenar.
- AnunciarRaiz(id): si ignoramos el nodo, le solicitamos al emisor.
3. Faro periodico (difundir_raiz cada 5 s): broadcast del hash del
manifiesto actual. Cadencia medida contra reloj::milisegundos(),
no contra los awaits — el interprete wasmi de los apps degrada
la cadencia de EsperaFrame::await a varios cientos de ms, asi
que se mide contra el reloj monotono y los oficios per-fotograma
se enganchan al tic del compositor (cuyo latido es fiable).
Contadores ResumenAkasha (rx/tx por variante, descartados, cola del
usuario) listos para un futuro indicador AoE en la barra de tareas.
Cambios complementarios:
- sys_net_recibir lee de akasha::pop_usuario, no de
drivers::red::recibir_en (que queda #[allow(dead_code)] como
primitiva del driver para diagnostico).
- tarea_red queda corta: envia un ARP al gateway y termina. El
demuxer y el faro viven en el tic del compositor.
Verificacion:
- 'cargo test -p akasha' → 6 pruebas en verde.
- QEMU headless 60 s con -object filter-dump → 14 frames: 11
AnunciarRaiz (Δ promedio 5.86 s sobre 5.00 s de target), 2 ARP
y el pregon hello. Cada AnunciarRaiz lleva el hash del manifiesto
'2f3deadfcc7dae25..' en 33 bytes postcard sobre 47 bytes de frame.
- COM1 vuelca 'akasha :: ANUNCIO emitido :: raiz=2f3deadfcc7dae25..'
en cada disparo.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,9 @@
|
||||
// * sys_tono — hacer sonar la bocina del PC (Fase 12);
|
||||
// * sys_net_mac — leer la MAC de la tarjeta de red (Fase 19);
|
||||
// * sys_net_enviar — enviar un frame Ethernet crudo (Fase 19);
|
||||
// * sys_net_recibir — leer el siguiente frame recibido (Fase 19).
|
||||
// * sys_net_recibir — leer el siguiente frame recibido (Fase 19;
|
||||
// desde la Fase 20, los frames Akasha se filtran
|
||||
// en el kernel y no llegan al userspace).
|
||||
//
|
||||
// GUARDARRAIL: el kernel valida MATEMATICAMENTE todo puntero que el modulo le
|
||||
// entrega contra los limites reales de su memoria lineal. No se confia en que
|
||||
@@ -530,10 +532,14 @@ pub(crate) fn enlazar_capacidades(
|
||||
)?;
|
||||
|
||||
// --- CAPACIDAD 14 :: sys_net_recibir(salida, capacidad) -> i32 ---
|
||||
// Saca el siguiente frame de la cola RX del dispositivo y lo copia en
|
||||
// `salida`. Devuelve los bytes copiados (>0), 0 si no hay frame pendiente,
|
||||
// o -1 si no hay red montada. La cola RX es del dispositivo y se comparte
|
||||
// entre los apps: el primero que pregunte se lleva el paquete.
|
||||
// Saca el siguiente frame de la cola del USUARIO y lo copia en `salida`.
|
||||
// Desde la Fase 20, esa cola la rellena el demultiplexor del kernel
|
||||
// (`akasha::drenar_y_demultiplexar`): los frames Akasha (`0x88B5` con
|
||||
// payload valido) se procesan en el nucleo y NO llegan aqui; el resto
|
||||
// del trafico —ARP, IPv4 de QEMU, futuros protocolos— si. Devuelve los
|
||||
// bytes copiados (>0), 0 si no hay frame pendiente, o -1 si no hay red
|
||||
// montada. La cola se vacia FIFO; si un app no llama nunca, los frames
|
||||
// mas antiguos se descartan al desbordar (ver `akasha::COLA_USUARIO`).
|
||||
enlazador.func_wrap(
|
||||
"renaser",
|
||||
"sys_net_recibir",
|
||||
@@ -555,10 +561,10 @@ pub(crate) fn enlazar_capacidades(
|
||||
"WASM :: sys_net_recibir desbordo la memoria lineal",
|
||||
)?;
|
||||
}
|
||||
// Bufer kernel-side donde el driver vuelca el frame; luego se copia
|
||||
// a la memoria del app en una sola pasada.
|
||||
// Bufer kernel-side donde la cola del usuario vuelca el frame; luego
|
||||
// se copia a la memoria del app en una sola pasada.
|
||||
let mut buf: alloc::vec::Vec<u8> = alloc::vec![0u8; capacidad as usize];
|
||||
let n = crate::drivers::red::recibir_en(&mut buf);
|
||||
let n = crate::akasha::pop_usuario(&mut buf);
|
||||
if n == 0 {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user