mirror of
https://github.com/ShadowKatStudios/OC-Minitel.git
synced 2024-11-23 02:28:05 +11:00
Updated the OpenOS vTunnel client, added pcap output to the vTunnel bridge.
This commit is contained in:
parent
970926efb6
commit
11ec131ab8
@ -1,88 +1,142 @@
|
||||
local vcomp = require "vcomponent"
|
||||
local vcomponent = require "vcomponent"
|
||||
local serial = require "serialization"
|
||||
local component = require "component"
|
||||
local computer = require "computer"
|
||||
local imt = require "interminitel"
|
||||
local event = require "event"
|
||||
local internet = component.internet
|
||||
local imt = require "interminitel"
|
||||
|
||||
local addr, raddr = vcomp.uuid(),vcomp.uuid()
|
||||
local poll = 0.5
|
||||
local listener, timer
|
||||
local socket
|
||||
local cfg = {}
|
||||
cfg.peers = {}
|
||||
cfg.rtimer = 5
|
||||
cfg.katimer = 30
|
||||
local listeners = {}
|
||||
local timers = {}
|
||||
local proxies = {}
|
||||
|
||||
-- dumb keepalive stuff
|
||||
local keepalive = 30
|
||||
local katimer
|
||||
|
||||
function start(faddr)
|
||||
if listener then return end
|
||||
if faddr then
|
||||
local host,nport = faddr:match("(.+):(%d+)")
|
||||
local function loadcfg()
|
||||
local f = io.open("/etc/vtunnel.cfg","rb")
|
||||
if not f then return false end
|
||||
for k,v in pairs(serial.unserialize(f:read("*a")) or {}) do
|
||||
cfg[k] = v
|
||||
end
|
||||
local iaddr,port = host or faddr or "shadowkat.net", tonumber(nport) or 4096
|
||||
socket = internet.connect(iaddr,port)
|
||||
print("Connecting to "..iaddr..":"..tostring(port).."...")
|
||||
repeat
|
||||
os.sleep(0.5)
|
||||
until socket.finishConnect()
|
||||
print("Connected!")
|
||||
|
||||
local proxy = {}
|
||||
local rbuffer = ""
|
||||
local timer = nil
|
||||
|
||||
function listener(t)
|
||||
rbuffer=rbuffer..(socket.read(4096) or "")
|
||||
if imt.decodePacket(rbuffer) then
|
||||
computer.pushSignal("modem_message",addr,raddr,0,0,imt.decodePacket(rbuffer))
|
||||
rbuffer = imt.getRemainder(rbuffer) or ""
|
||||
end
|
||||
if t == "internet_ready" and timer then
|
||||
event.cancel(timer)
|
||||
timer = nil
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
local function savecfg()
|
||||
local f = io.open("/etc/vtunnel.cfg","wb")
|
||||
if not f then
|
||||
print("Warning: unable to save configuration.")
|
||||
return false
|
||||
end
|
||||
timer = event.timer(poll,listener,math.huge) -- this is only here because OCEmu doesn't do internet_ready
|
||||
event.listen("internet_ready",listener)
|
||||
|
||||
-- also dumb keepalive stuff, fix this later
|
||||
katimer = event.timer(keepalive,function()
|
||||
socket.write("\0\1\0")
|
||||
end,math.huge)
|
||||
f:write(serial.serialize(cfg))
|
||||
f:close()
|
||||
end
|
||||
|
||||
local function createTunnel(host,port,addr,raddr)
|
||||
local proxy = {address=addr,buffer=""}
|
||||
function proxy.connect()
|
||||
if proxy.socket then
|
||||
proxy.socket.close()
|
||||
end
|
||||
proxy.socket = component.internet.connect(host,port)
|
||||
local st = computer.uptime()
|
||||
repeat
|
||||
coroutine.yield()
|
||||
until proxy.socket.finishConnect() or computer.uptime() > st+5
|
||||
end
|
||||
function proxy.send(...)
|
||||
socket.write(imt.encodePacket(...))
|
||||
rt = 0
|
||||
while not proxy.socket.write(imt.encodePacket(...)) and rt < 10 do
|
||||
proxy.connect()
|
||||
rt = rt + 1
|
||||
end
|
||||
proxy.last = computer.uptime()
|
||||
end
|
||||
|
||||
function proxy.maxPacketSize()
|
||||
return 12288
|
||||
function proxy.read()
|
||||
local rb, r
|
||||
local rt = 0
|
||||
while true do
|
||||
rb,r = proxy.socket.read(4096)
|
||||
if rb or rt > 10 then break end
|
||||
if type(rb) == "nil" then
|
||||
proxy.connect()
|
||||
end
|
||||
rt = rt + 1
|
||||
end
|
||||
proxy.buffer = proxy.buffer .. rb
|
||||
while imt.decodePacket(proxy.buffer) do
|
||||
computer.pushSignal("modem_message",addr,raddr,0,0,imt.decodePacket(proxy.buffer))
|
||||
proxy.buffer = imt.getRemainder(proxy.buffer) or ""
|
||||
end
|
||||
if computer.uptime() > proxy.last + cfg.katimer then
|
||||
proxy.socket.write("\0\1\0")
|
||||
proxy.last = computer.uptime()
|
||||
end
|
||||
end
|
||||
|
||||
proxy.type = "tunnel"
|
||||
proxy.slot = 4096
|
||||
|
||||
local docs = {
|
||||
send = "function(data...) -- Sends the specified data to the card this one is linked to.",
|
||||
maxPacketSize = "function():number -- Gets the maximum packet size (config setting)."
|
||||
}
|
||||
vcomp.register(addr,"tunnel",proxy,docs)
|
||||
event.listen("internet_ready",proxy.read)
|
||||
listeners[addr] = {"internet_ready",proxy.read}
|
||||
timers[addr] = event.timer(cfg.rtimer, proxy.read, math.huge)
|
||||
proxy.connect()
|
||||
proxy.last = computer.uptime()
|
||||
return proxy
|
||||
end
|
||||
|
||||
function start()
|
||||
loadcfg()
|
||||
for k,v in pairs(cfg.peers) do
|
||||
print(string.format("Connecting to %s:%d",v.host,v.port))
|
||||
v.addr = v.addr or vcomponent.uuid()
|
||||
v.raddr = v.raddr or vcomponent.uuid()
|
||||
local px = createTunnel(v.host, v.port, v.addr, v.raddr)
|
||||
vcomponent.register(v.addr, "tunnel", px)
|
||||
proxies[v.addr] = px
|
||||
end
|
||||
end
|
||||
function stop()
|
||||
if listener then
|
||||
event.ignore("internet_ready",listener)
|
||||
listener = nil
|
||||
for k,v in pairs(listeners) do
|
||||
event.ignore(v[1],v[2])
|
||||
end
|
||||
if timer then
|
||||
event.cancel(timer)
|
||||
timer = nil
|
||||
for k,v in pairs(timers) do
|
||||
event.cancel(v)
|
||||
end
|
||||
if katimer then
|
||||
event.cancel(katimer)
|
||||
katimer = nil
|
||||
for k,v in pairs(proxies) do
|
||||
vcomponent.unregister(k)
|
||||
end
|
||||
if component.type(addr) then
|
||||
vcomp.unregister(addr)
|
||||
end
|
||||
socket.close()
|
||||
end
|
||||
|
||||
function settimer(time)
|
||||
time = tonumber(time)
|
||||
if not time then
|
||||
print("Timer must be a number.")
|
||||
return false
|
||||
end
|
||||
cfg.rtime = time
|
||||
savecfg()
|
||||
end
|
||||
|
||||
function addpeer(host,port)
|
||||
port = tonumber(port) or 4096
|
||||
local t = {}
|
||||
t.host = host
|
||||
t.port = port
|
||||
t.addr = vcomponent.uuid()
|
||||
t.raddr = vcomponent.uuid()
|
||||
cfg.peers[#cfg.peers+1] = t
|
||||
print(string.format("Added peer #%d (%s:%d) to the configuration.\nRestart to apply changes.",#cfg.peers,host,port))
|
||||
savecfg()
|
||||
end
|
||||
|
||||
function listpeers()
|
||||
for k,v in pairs(cfg.peers) do
|
||||
print(string.format("#%d (%s:%d)\n Local address: %s\n Remote address: %s",k,v.host,v.port,v.addr,v.raddr))
|
||||
end
|
||||
end
|
||||
function delpeer(n)
|
||||
n=tonumber(n)
|
||||
if not n then
|
||||
print("delpeer requires a number, representing the peer number, as an argument.")
|
||||
return false
|
||||
end
|
||||
local dp = table.remove(cfg.peers, n)
|
||||
savecfg()
|
||||
print(string.format("Removed peer %s:%d",dp.host, dp.port))
|
||||
end
|
||||
|
@ -8,23 +8,13 @@ The protocol is documented [here](vtunnel-protocol.md)
|
||||
|
||||
## Setup
|
||||
|
||||
### Server
|
||||
|
||||
#### Requirements
|
||||
### Server Requirements
|
||||
|
||||
- Some form of unix-like
|
||||
- Lua 5.2 or 5.3
|
||||
- Luasocket
|
||||
|
||||
#### Running the server
|
||||
|
||||
At present, all you need to do is run bridge.lua, for example:
|
||||
|
||||
```
|
||||
lua53 bridge.lua [port] [timeout]
|
||||
```
|
||||
|
||||
### Client
|
||||
### Client Installation
|
||||
|
||||
#### OPPM
|
||||
|
||||
@ -37,33 +27,46 @@ oppm install vtunnel
|
||||
1. Install vtunnel.lua to /etc/rc.d
|
||||
2. Install interminitel.lua to /usr/lib
|
||||
|
||||
#### Running
|
||||
### Client setup
|
||||
|
||||
#### Creating a connection
|
||||
Many connections can be configured. To add one:
|
||||
|
||||
```
|
||||
rc vtunnel addpeer <server address> <server port>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Running the server
|
||||
|
||||
At present, all you need to do is run bridge.lua, for example:
|
||||
|
||||
```
|
||||
lua53 bridge.lua [port] [timeout]
|
||||
```
|
||||
|
||||
### Client
|
||||
|
||||
vTunnel is invoked as follows:
|
||||
|
||||
```
|
||||
rc vtunnel start <server address>:<server port>
|
||||
rc vtunnel start
|
||||
```
|
||||
|
||||
This will create a virtual linked card component connected to server\_address:server\_port.
|
||||
|
||||
#### Configuration
|
||||
|
||||
vTunnel can also be configured to start automatically. First, one would enable the rc service:
|
||||
vTunnel can also be configured to start automatically:
|
||||
|
||||
```
|
||||
rc vtunnel enable
|
||||
```
|
||||
|
||||
Then, edit /etc/rc.cfg and add a line as follows:
|
||||
There are several other commands available under `rc vtunnel`:
|
||||
|
||||
```
|
||||
vtunnel = "server.address:port"
|
||||
```
|
||||
- settimer - allows you to configure how often vTunnel polls the TCP socket
|
||||
- listpeers - shows which peers are configured, and the associated tunnel card addresses
|
||||
- delpeer - deletes a peer from the configuration, as shown in listpeers
|
||||
|
||||
Leaving it as default will result in vTunnel connecting to the public SKS bridge.
|
||||
|
||||
#### Minitel configuration
|
||||
### Minitel configuration
|
||||
|
||||
1. Disable minitel with rc - `rc minitel disable`
|
||||
2. Enable vtunnel with rc - `rc vtunnel enable`
|
||||
|
@ -1,9 +1,10 @@
|
||||
local socket = require "socket"
|
||||
local imt = require "interminitel"
|
||||
local pcap = require "pcap"
|
||||
|
||||
local tArgs = {...}
|
||||
|
||||
local port, timeout = tonumber(tArgs[1]) or 4096, tonumber(tArgs[2]) or 60
|
||||
local port, timeout, pf = tonumber(tArgs[1]) or 4096, tonumber(tArgs[2]) or 60, tArgs[3]
|
||||
|
||||
local clients, coroutines, messages = {}, {}, {}
|
||||
|
||||
@ -101,6 +102,14 @@ function pushLoop()
|
||||
reprint("Message #"..tostring(id).." (Client #"..tostring(msg[2]).." -> Client #"..tostring(k)..") - "..msg[1])
|
||||
end
|
||||
end
|
||||
if pf then
|
||||
local f=io.open(pf,"ab")
|
||||
if f then
|
||||
f:write(pcap.packet(msg[1]))
|
||||
print(pcap.packet(msg[1]))
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
messages[id] = nil
|
||||
end
|
||||
@ -126,6 +135,16 @@ end
|
||||
|
||||
spawn(bufferLoop)
|
||||
|
||||
if pf then
|
||||
local f=io.open(pf,"wb")
|
||||
if f then
|
||||
f:write(pcap.header())
|
||||
f:close()
|
||||
else
|
||||
pf=nil
|
||||
end
|
||||
end
|
||||
|
||||
while #coroutines > 0 do
|
||||
for k,v in pairs(coroutines) do
|
||||
coroutine.resume(v)
|
||||
|
Loading…
Reference in New Issue
Block a user