local Thread = require("thread")
local Core = require("computer")
local Monitor = require("event")
local Main = require("component")
local File = require("filesystem")--注册模块
local MO = {}
local TU = {}--注册硬件
local TTL = 0
local Time = "Unknown"
local Sender = "Unknown"
local Receiver = "Unknown"
local Header = "Unknown"
local Body = "Unknown"
local Proxy = "Unknown"
local Addr = "Unknown"--注册帧段
DNS = {}
DNS.main = {}
DNS.communi = {}
DNS.data = {}
DNS.data.resolute = {}
DNS.URL = {}
DNS.IPA = {}
DNS.Header = {
["Command"] = true,
["Say"] = true,
["callBack"] = true,
["Addr"] = true,
["Report"] = true
}--注册DNS组件
local e = "ERROR"
local w = "WARNING"
local i = "INFO"--注册缩写
DNS.ARS = {}
DNS.AuS = {}
DNS.Update = {}
DNS.timer = {}--注册线程组
local adminPassword = "password"--设置管理员密码
function DNS.main.load()--加载数据库到内存
local member = "main.load"
local URL, IPA = io.open("URL.lua", "r"), io.open("IPA.lua", "r")
io.input(URL)
if URL ~= nil then
if io.read() ~= "DNS: URL.lua: Database_Header" then
DNS.main.call(w, member, "ILG_DB", "rewrite")
DNS.main.create("addr")
URL = io.open("URL.lua", "r")
end
else
DNS.main.call(w, member, "NO_DB", "rewrite")
DNS.main.create("addr")
URL = io.open("URL.lua", "r")
end
io.input(IPA)
if IPA ~= nil then
if io.read() ~= "DNS: IPA.lua: Database_Header" then
DNS.main.call(w, member, "ILG_DB", "rewrite")
DNS.main.create("proxy")
IPA = io.open("IPA.lua", "r")
end
else
DNS.main.call(w, member, "ILG_DB", "rewrite")
DNS.main.create("proxy")
IPA = io.open("IPA.lua", "r")
end
if URL == nil or IPA == nil then
DNS.main.call(e, member, "UNK_ER", "untergebrochen")
error(0)
end
DNS.main.call(i, member, "DB_LD", "fortfahren")
io.input(URL)
while true do
local url = io.read()
if url then
local addr = io.read()
DNS.URL[url] = addr
else
break
end
end
io.input(IPA)
while true do
local addr = io.read()
if addr then
local proxy = io.read()
DNS.IPA[addr] = proxy
else
break
end
end
return true
end
function DNS.main.create(target)--对被篡改的或者未找到的数据库进行重新建立
local member = "main.create"
if target == "addr" then
local url = io.open("URL.lua", "w")
url:write("DNS: URL.lua: Database_Header\nDNS\n"..MO.address)
url:close()
elseif target == "proxy" then
local ipa = io.open("IPA.lua", "w")
ipa:write("DNS: IPA.lua: Database_Header\n")
ipa:close()
else
DNS.main.call(e, member, "BAD_ARG", "fortfahren")
return false
end
return true
end
function DNS.main.init()--初始化DNS服务器
local member = "main.init"
local port = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,80,8080}
local hardware = Main.list("modem")()
if hardware ~= nil then
MO = Main.proxy(Main.list("modem")())
DNS.main.call(i, member, "HW_LD", "fortfahren")
else
DNS.main.call(e, member, "HW_MS", "untergebrochen")
error(0)
end
hardware = Main.list("tunnel")()
if hardware ~= nil then
TU = Main.proxy(Main.list("tunnel")())
DNS.main.call(i, member, "HW_LD", "fortfahren")
else
DNS.main.call(w, member, "HW_MS", "fortfahren")
end
for key, val in pairs(port) do
MO.open(val)
end
DNS.main.load()
DNS.main.watcher()
return true
end
function DNS.main.call(range, reporter, class, status)--输出日志信息
local member = "main.call"
print("["..os.date().."] ["..range.."] DNS."..reporter..": "..class.." status: "..status)
end
function DNS.main.callR(range, reporter, class, status, receiver)--反馈callBack信息
local member = "main.call"
print("["..os.date().."] ["..range.."] from "..receiver..": DNS."..reporter..": "..class.." status: "..status)
MO.send(DNS.data.proxy(receiver), 1, 100, os.date(), "DNS", DNS.data.resolute.url(receiver), "callBack", "["..os.date().."] ["..range.."] DNS."..reporter..": "..class.." status: "..status)
end
function DNS.main.watcher()--看门狗,用来在按下特定按键时kill掉主进程达到结束后台的目的。
local member = "main.WATCHER"
local watcher = Thread.create(function()
while true do
local typ, addr, key_1, key_2 = Monitor.pull("key_down")
if key_1 == 0 and key_2 == 54 then DNS.main.call(i, member, "PRG_END", "Main Thread has been killed by DNS.main.WATCHER.") main:kill() end
end
end)
end
function DNS.communi.monitor()--创建主监视器
DNS.main.init()
local member = "communi.monitor"
DNS.main.call(i, member, "MT_LD", "fortfahren")
local main = Thread.create(function()
while true do
while true do
_, localAddr, remoteAddr, port, distance, TTL, Time, Sender, Receiver, Header, Body = Monitor.pull("modem_message")
if TTL <= 0 then break end
TTL = TTL-1
Sender = DNS.data.resolute.url(Sender)
if Sender == nil then DNS.main.call(e, member, "UNK_SED", "abuntergebrochen") break end
if Receiver == "DNS" then
if Header == "Addr" then
table.insert(DNS.ARS, Thread.create(DNS.data.ARS(Sender, Header, Body)))
elseif Header == "Command" then
table.insert(DNS.AuS, Thread.create(DNS.communi.AuS(Sender, Header, Body)))
elseif Header == "Say" then
DNS.main.callR(e, member, "NO_PER", "REF", DNS.data.resolute.addr(Sender))
break
elseif Header == "callBack" then
print("["..os.date().."] [INFO] [callBack] from "..Sender..": "..Body)
elseif Header == "Report" then
local proxy = ""
local time = 0
for word in pairs(Body, "%w+") do
proxy = proxy..word
time = time + 1
if time == 5 then break end
proxy = proxy.."-"
end
DNS.data.IPAupdate(DNS.data.resolute.addr(Sender), proxy)
end
end
Receiver = DNS.data.resolute.addr(Receiver)
if Receiver == nil then DNS.main.callR(e, member, "UNK_REC", "abuntergebrochen", DNS.resolute.addr(Sender)) break end
MO.send(DNS.data.proxy(Receiver), 1, TTL, Time, Sender, Receiver, Header, Body)
end
end
end)
os.execute("clear")
DNS.main.call(i, member, "Press right SHIFT to kill the monitor.", "fortfahren")
print("\n\n")
DNS.main.call(i, member, "Press ctrl+alt+C to continue.", "fortfahren")
print("\n\n")
end
function DNS.communi.AuS(sender, header, body)--鉴权
local member = "communi.AuS"
MO.send(DNS.data.proxy(sender), 1, 100, os.date(), "DNS", DNS.data.resolute.addr(sender), "Command", "Authentication.")
table.insert(DNS.timer, Thread.create(function() os.sleep(20) DNS.ARS[pos]:kill() return end))
local posT = #DNS.timer
while true do
local _, localeAdre, remoteAdre, anschluss, abstand, ttl, zeit, sed, empfaenger, kopf, koerper = Monitor.pull("modem_message")
if sed == sender and kopf == "Command" and koerper == "password" then break
elseif sed == sender and kopf == "Command" and koerper ~= adminPassword then DNS.main.callR(e, member, "NO_PER", "abgelehnt", DNS.resolute.addr(sender)) return false end
end
DNS.timer[posT]:kill()
DNS.main.calR(i, member, "CMD_ACP", "fortfahren", DNS.resolute.addr(sender))
os.execute(body)
return true
end
function DNS.data.resolute.addr(target)--ARS服务,强制解析为MAC地址
local member = "data.resolute.addr"
for addr, url in pairs(DNS.URL) do
if target == addr or target == url then return addr end
end
return nil
end
function DNS.data.resolute.change(target)--ARS服务,切换解析内容
local member = "data.resolute.change"
for addr, url in pairs(DNS.URL) do
if target == addr then return url end
if target == url then return addr end
end
return nil
end
function DNS.data.resolute.url(target)--ARS服务,强制解析为URL
local member = "data.resolute.url"
for addr, url in pairs(DNS.URL) do
if target == addr or target == url then return url end
end
return nil
end
function DNS.data.proxy(target)--ARS服务,解析所在服务区
local member = "data.proxy"
for addr, proxy in pairs(DNS.IPA) do
if target == addr or target == proxy then return proxy end
end
return nil
end
function DNS.data.ARS(sender, header, body)--ARS远程解析服务
local member = "data.ARS"
local pos = #DNS.ARS
local message = {}
for word in string.gmatch(body, "a%+") do
table.insert(message, word)
end
if message[1] == "download" then
if message[2] then DNS.main.callR(e, member, "BAD_ARG", "untergebrochen", DNS.resolute.addr(sender)) return false end
MO.send(DNS.data.proxy(sender), 1, 100, os.date(), "DNS", DNS.data.resolute.addr(sender), "Addr", "Request accepted.")
table.insert(DNS.timer, Thread.create(function() os.sleep(10) DNS.ARS[pos]:kill() return end))
local posT = #DNS.timer
while true do
local _, localeAdre, remoteAdre, anschluss, abstand, ttl, zeit, sed, empfaenger, kopf, koerper = Monitor.pull("modem_message")
if sed == sender and kopf == "Addr" and koerper == "ready." then break end
end
DNS.timer[posT]:kill()
for addr, url in pairs(DNS.URL) do
MO.send(DNS.data.proxy(sender), 1, 100, os.date(), "DNS", DNS.data.resolute.addr(sender), "Addr", addr.." "..url)
end
MO.send(DNS.data.proxy(sender), 1, 100, os.date(), "DNS", DNS.data.resolute.addr(sender), "Addr", "Request ended.")
return true
elseif message[1] == "request" then
if message[3] then DNS.main.callR(e, member, "BAD_ARG", "untergebrochen", DNS.resolute.addr(sender)) return false end
MO.send(DNS.data.proxy(sender), 1, 100, os.date(), "DNS", DNS.data.resolute.addr(sender), "Addr", DNS.data.change(body[2]))
return true
elseif message[1] == "update" then
if message[3] then DNS.main.callR(e, member, "BAD_ARG", "untergebrochen", DNS.resolute.addr(sender)) return false end
DNS.data.URLupdate(sender, message[2])
else
DNS.main.callR(e, member, "BAD_ARG", "untergebrochen", DNS.resolute.addr(sender))
return false
end
return true
end
function DNS.data.URLupdate(target, url)--刷新URL数据
for addr, val in pairs(DNS.URL) do
if target == addr then
if val ~= url then
DNS.URL[target] = url
DNS.data.writeDownown("addr")
DNS.main.call(i, member, "DB_UPD", "fortfahren")
else return true end
end
end
return true
end
function DNS.data.IPAupdate(target, proxy)--刷新IPA数据
for addr, server in pairs(DNS.IPA) do
if target == addr then
if server ~= proxy then
DNS.IPA[target] = proxy
DNS.data.writeDownown("proxy")
DNS.main.call(i, member, "DB_UPD", "fortfahren")
else return true end
end
end
return true
end
function DNS.data.writeDown(target)--将内容写至数据库
if target == "addr" then
DNS.main.create(target)
local file = io.open("URL.lua", "a")
io.output(file)
for addr, url in pairs(DNS.URL) do
io.write(addr.."\n")
io.write(url.."\n")
end
io.close(file)
elseif target == "proxy" then
DNS.main.create(target)
local file = io.open("IPA.lua", "a")
io.output(file)
for addr, proxy in pairs(DNS.IPA) do
io.write(addr.."\n")
io.write(proxy.."\n")
end
io.close(file)
end
end