OverviewFilesCommitsIssuesDocsReleasesPeers

hyperident-gateway / test / test-utun.js

182 lines · javascript ref:
/**
 * UTUNManager Test
 *
 * NOTE: This test requires root/sudo privileges to create TUN devices
 * Run with: sudo bare test/test-utun.js
 */

import { UTUNManager } from '../lib/utun-manager.js'
import { GatewayIdentity } from '../lib/gateway-identity.js'

console.log('🧪 UTUNManager Test\n')
console.log('⚠️  Note: This test may require root/sudo privileges on some systems')
console.log('============================================================\n')

async function runTests() {
  let utunManager = null

  try {
    // Test 1: Create GatewayIdentity
    console.log('📝 Test 1: Initialize GatewayIdentity')
    const identity = new GatewayIdentity({
      subnet: '10.22.0.0/16',
      staticMappings: {
        'test-service': '10.22.100.50'
      }
    })

    // Register a test service using static IP (no hyperident profile needed)
    const testTopic = Buffer.alloc(32) // Mock topic
    identity.services.set('10.22.100.50', {
      name: 'test-service',
      profile: 'test-service',
      ip: '10.22.100.50',
      topic: testTopic,
      port: 9418,
      connections: []
    })

    const service = identity.lookup('10.22.100.50')
    console.log(`✅ Test service registered: ${service.name} -> ${service.ip}:${service.port}\n`)

    // Test 2: Create UTUNManager
    console.log('📝 Test 2: Create UTUNManager')

    let packetsReceived = 0

    utunManager = new UTUNManager({
      deviceName: 'tun0',
      gatewayIP: '10.22.0.1',
      subnet: '10.22.0.0/16',
      netmask: '255.255.0.0',
      mtu: 1500,
      gatewayIdentity: identity,
      onPacketReceived: (data) => {
        packetsReceived++
        console.log(`\n📦 Packet received:`)
        console.log(`   From: ${data.ipPacket.srcIP}`)
        console.log(`   To: ${data.ipPacket.dstIP}`)
        console.log(`   Service: ${data.service.name}`)
        console.log(`   Protocol: ${data.ipPacket.protocol}`)
        console.log(`   Size: ${data.packet.length} bytes`)
      },
      onError: (err) => {
        console.error(`❌ Error: ${err.message}`)
      }
    })

    console.log('✅ UTUNManager created\n')

    // Test 3: Open TUN device
    console.log('📝 Test 3: Open TUN device')
    await utunManager.open()
    console.log()

    // Test 4: Test packet parsing
    console.log('📝 Test 4: Test packet parsing')

    const testPacket = UTUNManager.buildIPv4Packet({
      srcIP: '10.22.0.100',
      dstIP: '10.22.100.50',
      protocol: 6, // TCP
      payload: Buffer.from('Hello from TUN!')
    })

    console.log('   Built test packet:')
    console.log(`   Length: ${testPacket.length} bytes`)
    console.log(`   First bytes: ${testPacket.subarray(0, 20).toString('hex')}`)

    const parsed = utunManager._parseIPPacket(testPacket)
    console.log(`   Parsed successfully:`)
    console.log(`     Version: IPv${parsed.version}`)
    console.log(`     Src: ${parsed.srcIP}`)
    console.log(`     Dst: ${parsed.dstIP}`)
    console.log(`     Protocol: ${parsed.protocol}`)
    console.log(`     Payload: ${parsed.payload.length} bytes`)
    console.log()

    // Test 5: Get statistics
    console.log('📝 Test 5: Get statistics')
    const stats = utunManager.getStats()
    console.log('   TUN Device Info:')
    console.log(`     Name: ${stats.tun.name}`)
    console.log(`     RX packets: ${stats.tun.rxPackets}`)
    console.log(`     TX packets: ${stats.tun.txPackets}`)
    console.log(`     RX bytes: ${stats.tun.rxBytes}`)
    console.log(`     TX bytes: ${stats.tun.txBytes}`)
    console.log(`     RX drops: ${stats.tun.rxDrop}`)
    console.log()
    console.log('   Manager Stats:')
    console.log(`     Packets received: ${stats.packetsReceived}`)
    console.log(`     Packets sent: ${stats.packetsSent}`)
    console.log(`     Bytes received: ${stats.bytesReceived}`)
    console.log(`     Bytes sent: ${stats.bytesSent}`)
    console.log(`     Packets dropped: ${stats.packetsDropped}`)
    console.log(`     Errors: ${stats.errors}`)
    console.log(`     Is running: ${stats.isRunning}`)
    console.log()

    // Test 6: Write packet to TUN
    console.log('📝 Test 6: Write packet to TUN interface')
    console.log('   Attempting to write test packet...')

    const responsePacket = UTUNManager.buildIPv4Packet({
      srcIP: '10.22.100.50',
      dstIP: '10.22.0.100',
      protocol: 6,
      payload: Buffer.from('Response from service!')
    })

    const written = await utunManager.writePacket(responsePacket)
    console.log(`   ✅ Wrote ${written} to TUN interface`)
    console.log()

    // Test 7: Wait for incoming packets
    console.log('📝 Test 7: Listening for incoming packets')
    console.log('   Waiting 3 seconds for packets...')
    console.log('   Try: ping 10.22.100.50')
    console.log('   Or:  curl http://10.22.100.50:9418')
    console.log()

    await new Promise(resolve => setTimeout(resolve, 3000))

    if (packetsReceived > 0) {
      console.log(`\n✅ Received ${packetsReceived} packets during test`)
    } else {
      console.log(`\n⚠️  No packets received (this is normal if no traffic sent)`)
    }
    console.log()

    // Test 8: Final statistics
    console.log('📝 Test 8: Final statistics')
    const finalStats = utunManager.getStats()
    console.log(`   Total packets processed: ${finalStats.packetsReceived}`)
    console.log(`   Total bytes: ${finalStats.bytesReceived}`)
    console.log()

    console.log('============================================================')
    console.log('✅ All tests completed successfully!')
    console.log('============================================================')
    console.log()
    console.log('Next steps:')
    console.log('- Implement HyperswarmRouter for P2P packet forwarding')
    console.log('- Integrate UTUNManager with full gateway system')
    console.log('- Test end-to-end packet routing')
    console.log()

  } catch (error) {
    console.error('\n❌ Test failed:', error.message)
    console.error(error.stack)
    Bare.exitCode = 1
  } finally {
    // Cleanup
    if (utunManager) {
      console.log('🧹 Cleaning up...')
      await utunManager.close()
    }
  }
}

// Run tests
runTests()