#!/usr/bin/env python3

import time
from lib.tuntap import TunThread
from lib import dns
from lib import query
from lib.packet import Packet, PacketPool

hostname = b'vpn.bgpat.net'
query.Field.HostName.default = hostname
query.Field.HostName.pattern = hostname
Packet.hostname = hostname

txpool = PacketPool()
rxpool = PacketPool()


class VPNServer(TunThread):
    daemon = True
    name = 'tun0'
    addr = '192.168.200.1'
    gateway = '192.168.200.1'

    def receive(self, data):
        global rxpool
        pkt = Packet(data)
        rxpool.push(pkt)


tun = VPNServer()
tun.start()


class DNSServer(dns.ServerThread):
    daemon = True

    def receive(self, req, addr, port, data):
        txInit = query.TxInitialize(req)
        txSend = query.TxSend(req)
        rxRecv = query.Receive(req)
        rxPoll = query.Polling(req)
        if txInit.params is not None:
            params = txInit.params
            res = self.txinit(params['id'], params['count'])
            print('txinit', params)
        elif txSend.params is not None:
            params = txSend.params
            res = self.txsend(params['id'], params['sequence'], params['data'])
            print('txsend', params)
        elif rxRecv.params is not None:
            params = rxRecv.params
            res = self.rxrecv(params['id'], params['sequence'])
            print('rxrecv', params)
        elif rxPoll.params is not None:
            res = self.rxpoll()
            print('rxpoll')
        else:
            res = query.Error()
        return {
            'value': bytes(res),
            'type': res.type,
        }

    def txinit(self, id, count):
        global txpool
        txpool[id] = Packet(count)
        return query.Ok(count=count, sequence=count)

    def txsend(self, id, seq, data):
        global txpool
        pkt = txpool[id]
        pkt[seq] = data
        remain = pkt.count - len(pkt)
        if not remain:
            tun.send(pkt.unpack())
            del txpool[id]
        return query.Ok(count=pkt.count, sequence=seq)

    def rxrecv(self, id, seq):
        global rxpool
        pkt = rxpool[id]
        if seq in pkt:
            del pkt[seq]
        keys = list(pkt.keys())
        if len(keys):
            i = keys[0]
            return query.RxSend(data=pkt[i], sequence=i, id=id)
        else:
            del rxpool[id]
            return query.Error()

    def rxpoll(self):
        global rxpool
        if rxpool.empty():
            return query.Error()
        pkt = rxpool.front()
        if pkt.id in rxpool:
            return query.Error()
        rxpool[pkt.id] = pkt
        rxpool.pop()
        return query.RxInitialize(data=pkt[0], count=pkt.count, id=pkt.id)


dnsd = DNSServer()
dnsd.start()

while True:
    time.sleep(1)

@@ -1362,32 +1362,37 @@
 'rxrecv', params
+, req
 )%0A        elif r
@@ -1515,32 +1515,88 @@
 = query.Error()%0A
+        print('%3C ', res.__class__.__name__, res.params)%0A
         return %7B
@@ -2146,32 +2146,184 @@
   global rxpool%0A
+        if id not in rxpool:%0A            print('recv error', id, seq)%0A            print('rxpool', list(rxpool.keys()))%0A            return query.Error()%0A
         pkt = rx

Add debug code