Download Game! Currently 94 players. Last logged in:NatwShalkanKalaharFonkensemble

Blitzer's Blog >> 72917

Back to blogs index
Posted: 03 Oct 2026 19:36 [ permalink ]
TC$mC$ on tC$ydellinen arkkitehtoninen suunta. Kun rakennamme OOB-sillan
(Out-of-Band Bridge) tC$ysin konfiguraatio-ohjatuksi ja geneeriseksi, luot
kC$ytC$nnC6ssC$ Mesh-verkon ydinreitittimen (Core Router).
TC$llC$ mallilla yksi kevyt Node.js-prosessi voi istua risteyskohdassa ja
yhdistC$C$ TCP/UDP-verkot, sarjaportit (serial), IRC-kanavat,
HTTP-pollausrajapinnat ja tC$ysin ilmaraolla (airgap) eristetyt
USB-tiedostojC$rjestelmC$t toisiinsa saumattomasti.
Koska viestiformaatti on aina se sama riippumaton JSON-array ja deduplikointi
hoituu MsgId:n avulla, monisolmureititys (A -> B -> C) toimii tC$ysin
automaattisesti ilman, ettC$ reitittimien tarvitsee tietC$C$ koko verkon
topologiaa.
TC$ssC$ on suunnitelma ja prototyyppi tC$lle geneeriselle OOB-reitittimelle.
1. Reitittimen Konfiguraatio (router_config.json)
MC$C$ritellC$C$n konfiguraatio, joka on helppo lukea lennosta. Se jakaantuu
kahteen osaan: Transports (fyysiset/loogiset vC$ylC$t) ja Routes
(reititystaulu).
{
  "bridgeName": "Main-OOB-Router-1",
  "transports": {
    "airgap_vault": { 
      "type": "fs", 
      "inbox": "/media/usb_drive/in", 
      "outbox": "/media/usb_drive/out",
      "poll_ms": 5000 
    },
    "remote_site_b": {
      "type": "irc",
      "channel": "#mesh-site-b-link",
      "botName": "LinkBotA"
    },
    "legacy_serial": {
      "type": "serial",
      "port": "/dev/ttyUSB0",
      "baud": 115200
    }
  },
  "routes": {
    "airgap-*": "airgap_vault",
    "site-b-*": "remote_site_b",
    "hardware-controller": "legacy_serial",
    "default": "remote_site_b"
  }
}

2. Transport-Rajapinta (Plugin-arkkitehtuuri)
Jotta reititin pysyy geneerisenC$, jokainen OOB-vC$ylC$ (FS, Serial, IRC jne.)
kirjoitetaan omana pienenC$ plugininaan, jolla on tC$smC$lleen sama rajapinta.
TC$ssC$ esimerkkinC$ tuo mainitsemasi hakemistopohjainen (FS)
airgap-transport:
transports/fs_transport.js
import fs from 'fs';
import path from 'path';

export default class FSTransport {
    constructor(config, onIncomingOOB) {
        this.inbox = path.resolve(config.inbox);
        this.outbox = path.resolve(config.outbox);
        this.onIncomingOOB = onIncomingOOB; // Callback reitittimelle pC$in
        
        [this.inbox, this.outbox].forEach(d => { if (!fs.existsSync(d))
fs.mkdirSync(d, { recursive: true }); });
        
        // Pollaa Inboxia airgapin vastauksien varalta
        setInterval(() => this._poll(), config.poll_ms || 5000);
    }

    // Reititin kutsuu tC$tC$, kun verkosta tulee airgapille osoitettu paketti
    send(msgString, msgId) {
        const fileName = path.join(this.outbox, `msg_${msgId}_${Date.now()}.jso
n`);
        fs.writeFileSync(fileName, msgString, 'utf8');
    }

    _poll() {
        const files = fs.readdirSync(this.inbox);
        for (const file of files) {
            if (file.endsWith('.json')) {
                const filePath = path.join(this.inbox, file);
                try {
                    const rawData = fs.readFileSync(filePath, 'utf8');
                    this.onIncomingOOB(rawData); // Injektoidaan viesti
takaisin Meshiin!
                    fs.unlinkSync(filePath);
                } catch (e) { /* KC$sittele virhe (esim. tiedostoa vielC$
kirjoitetaan) */ }
            }
        }
    }
}

3. Ydin: Geneerinen OOB Bridge (oob_bridge.js)
TC$mC$ on ohjelman sydC$n. Se lataa konfiguraation, kC$ynnistC$C$ tarvittavat
Transport-pluginit, ja alkaa siirtC$C$ paketteja lokaalin IP-verkon ja
OOB-vC$ylien vC$lillC$ sC$C$ntC6jen mukaisesti.
import fs from 'fs';
import { HybridMeshNode } from './mesh.js';

/ Importoidaan dynaamisesti (tai staattisesti) plugin-luokat
import FSTransport from './transports/fs_transport.js';
const TRANSPORT_PLUGINS = { 'fs': FSTransport }; 

const config = JSON.parse(fs.readFileSync('router_config.json', 'utf8'));
const node = new HybridMeshNode(config.bridgeName);
const activeTransports = {};

async function main() {
    await node.start();
    console.log(`[OOB Router] ${config.bridgeName} kytketty lokaaliin
Mesh-verkkoon.`);

    // 1. Alustetaan kaikki konfiguroidut OOB-vC$ylC$t
    for (const [tName, tConfig] of Object.entries(config.transports)) {
        const PluginClass = TRANSPORT_PLUGINS[tConfig.type];
        if (PluginClass) {
            activeTransports[tName] = new PluginClass(tConfig, (rawString) =>
{
                // KUN OOB-VCYLCSTC TULEE VIESTI, INJEKTOIDAAN SE LOKAALIIN
MESH-VERKKOON
                console.log(`[OOB -> MESH] Vastaanotettu viesti vC$ylC$stC$:
${tName}`);
                node._handleIncoming(rawString, null, 'OOB');
            });
            console.log(`[OOB Router] Transport kytketty: ${tName}
(${tConfig.type})`);
        }
    }

    // 2. Kuunnellaan lokaalin Mesh-verkon viestejC$ ja reititetC$C$n ne
eteenpC$in OOB-vC$yliin
    for await (const msg of node.inbox) {
        if (msg.type === 0) continue; // Ei reititetC$ Gossip-viestejC$
OOB-linkkien yli (sC$C$stC$C$ kaistaa)

        let routed = false;
        
        // EtsitC$C$n sopiva reitti TargetID:n perusteella
        if (msg.targetId) {
            for (const [routePattern, transportName] of Object.entries(config.r
outes)) {
                if (routePattern === 'default') continue;
                
                // Yksinkertainen wildcard-match (esim. "airgap-*")
                const match = routePattern.endsWith('*') 
                    ? msg.targetId.startsWith(routePattern.slice(0, -1))
                    : msg.targetId === routePattern;

                if (match && activeTransports[transportName]) {
                    forwardToOOB(transportName, msg);
                    routed = true;
                    break;