Update LibNetwork

This commit is contained in:
Kirigaya Kazuto 2017-10-12 15:20:29 +08:00
parent ce6748c08f
commit 7b4cafb5b7

View File

@ -9,184 +9,193 @@
close=function(port):bool close=function(port):bool
} }
--]] --]]
local netcard=require("localNetcard") local netcard = require("localNetcard")
local event = require("event")
local uuid = require("uuid")
require("vector")
-- Check Netcard -- Check Netcard
if(netcard.broadcast==nil or if
netcard.send==nil or (netcard.broadcast == nil or netcard.send == nil or netcard.open == nil or netcard.isOpen == nil or
netcard.open==nil or netcard.close == nil)
netcard.isOpen==nil or then
netcard.close==nil) then
print("Error: netcard invalid.") print("Error: netcard invalid.")
end end
local sker= -- Socket Kernel Table local sker = {
{ -- Socket Kernel Table
fdset= -- Store information of sockets fdset = {} -- Store information of sockets
{ }
--[[
status : string ="Ready" "Connected" "Closed"
remote_hwport : int
remote_cookie : string
--]]
}
}
local arpker={} -- ARP Kernel Table local arpker = {} -- ARP Kernel Table
local tcp_syn = string.pack("iii", 1, 1, 1)
local tcp_synack = string.pack("iii", 1, 1, 3)
local tcp_ack = string.pack("iii", 1, 1, 2)
local arp_broadcast = string.pack("iii", 1, 0, 0)
local arp_quest = string.pack("iii", 1, 0, 1)
local dhcp_quest = string.pack("iii", 0, 0, 1)
local dhcp_ack = string.pack("iii", 0, 0, 2)
local trans_data = string.pack("iii", 1, 2, 1)
local trans_ack = string.pack("iii", 1, 2, 2)
function _findFirstAvaliableSocket() function _findFirstAvaliableSocket()
local i=0 local i = 0
while ( sker.fdset[i] ~= nil ) do i=i+1 end while (sker.fdset[i] ~= nil) do
i = i + 1
end
return i return i
end end
function _doCreateSocket(sfd) function _doCreateSocket(sfd)
if(sker.fdset[sfd]~=nil) then return false,"sfd invalid" if (sker.fdset[sfd] ~= nil) then
return false, "sfd invalid"
else else
sker.fdset[sfd]= sker.fdset[sfd] = {
{ status = "Ready",
status="Ready" -- remote_cookie
} -- local_cookie
return true,"Success" sendBus = Vector.new(),
recvBus = Vector.new()
}
return true, "Success"
end end
end end
function _getSocketStatus(sfd) function _getSocketStatus(sfd)
if(sker.fdset[sfd]==nil) then return nil if (sker.fdset[sfd] == nil) then
return nil
else else
return sker.fdset[sfd].status return sker.fdset[sfd].status
end end
end end
function _setSocketStatus(sfd,status,...) function _setSocketStatus(sfd, status, ...)
if(sker.fdset[sfd]==nil) then return false if (sker.fdset[sfd] == nil) then
return false
else else
sker.fdset[sfd].status=status sker.fdset[sfd].status = status
if(status=="Connected") then if (status == "Connected") then
sker.fdset[sfd].remote_hwport=arg[1] sker.fdset[sfd].remote_cookie = arg[1]
end end
return true return true
end end
end end
function _isPortValid(port) function _isPortValid(port)
return port>0 and port<65536 return port > 0 and port < 65536
end end
function _doConnect(sfd,remote_uuid,port) -- Connect to port 10 of a remote device with virtual port function _generateNewCookie() -- Generate a new cookie
return uuid.next()
end
function _doConnect(sfd, remote_uuid, port) -- Connect to port 10 of a remote device with virtual port
-- Send SYN package (1,1,1) -- Send SYN package (1,1,1)
local syn=string.pack("iii",1,1,1) local syn = tcp_syn
if(not netcard.send(remote_uuid,10,syn,port)) then if (not netcard.send(remote_uuid, 10, syn, port)) then
return -1,"Network error" return -1, "Network error"
end end
-- Wait 1.5 seconds for SYN+ACK (1,1,3) -- Wait 1.5 seconds for SYN+ACK (1,1,3)
local e,remote_hwport,remote_cookie=event.pull(1.5,"net_synack") local e, remote_cookie = event.pull(1.5, "net_synack")
if(e==nil) then if (e == nil) then
return -2,"Connection timed out" return -2, "Connection timed out"
end end
--- Send ACK package (1,1,2) --- Send ACK package (1,1,2)
local ack=string.pack("iii",1,1,2) local ack = tcp_ack
if(not netcard.send(remote_uuid,port,ack)) then local newcookie = _generateNewCookie()
return -1,"Network error" -- Update FDSet Cookie
sker.fdset[sfd].remote_cookie = remote_cookie
sker.fdset[sfd].local_cookie = newcookie
if (not netcard.send(remote_uuid, 10, ack, remote_cookie, newcookie)) then
return -1, "Network error"
end end
-- Connection established -- Connection established
return 0,"Success",remote_hwport return 0, "Success", remote_cookie
end end
function _isInArpCache(tag) -- Check ARP Check Table with tag for uuid function _isInArpCache(tag) -- Check ARP Check Table with tag for uuid
if(arpker[tag]~=nil) then if (arpker[tag] ~= nil) then
return true,arpker[tag].uuid return true, arpker[tag].uuid
else else
return false return false
end end
end end
function _generateARPQuest(tag) -- Generate a ARP quest function _doArpBroadcastQuery(header, tag) -- Broadcast ARP quest to hardware port 9 (arp)
local s=string.pack("iiii",1,0,1,string.length(tag)) if (netcard.broadcast(9, header, tag)) then
s=s..tag return true, "Success"
return s
end
function _doArpBroadcastQuery(tag) -- Broadcast ARP quest to hardware port 9 (arp)
if(netcard.broadcast(9,tag)) then return true,"Success"
else return false,"Netcard error"
end
function socket() -- Allocate a new socket
local idx=_findFirstAvaliableSocket()
local ret,emsg=_doCreateSocket(idx)
if(not ret) then
return -1,emsg
else else
return ret,emsg return false, "Netcard error"
end end
end end
function connect(sfd,remote_tag,port) -- Connect to a remote device function socket() -- Allocate a new socket
if(_getSocketStatus(sfd)~="Ready") then local idx = _findFirstAvaliableSocket()
return -1,"Socket not ready" local ret, emsg = _doCreateSocket(idx)
elseif(not _isPortValid(port)) then if (not ret) then
return -2,"Port Invalid" return -1, emsg
else
return ret, emsg
end
end
function connect(sfd, remote_tag, port) -- Connect to a remote device
if (_getSocketStatus(sfd) ~= "Ready") then
return -1, "Socket not ready"
elseif (not _isPortValid(port)) then
return -2, "Port Invalid"
else else
-- Try to resolve remote_tag to remote_uuid -- Try to resolve remote_tag to remote_uuid
local remote_uuid=do_arp_query(remote_tag) local remote_uuid = do_arp_query(remote_tag)
if(remote_uuid == nil) then if (remote_uuid == nil) then
return -3,"Tag can not be resolved into uuid" return -3, "Tag can not be resolved into uuid"
else else
local eret,emsg,remote_hwport,remote_cookie=_doConnect(sfd,remote_uuid,port) local eret, emsg, remote_cookie = _doConnect(sfd, remote_uuid, port)
if(eret==0) then if (eret == 0) then
_setSocketStatus(sfd,"Connected",remote_hwport,remote_cookie) _setSocketStatus(sfd, "Connected", remote_cookie)
return 0,"Success" return 0, "Success"
else else
return eret,emsg return eret, emsg
end end
end end
end end
end end
function bind(sfd,port) -- Bind socket at specific port function bind(sfd, port) -- Bind socket at specific port
end end
function listen(sfd,sz) -- Set size of queue for waiting connections function listen(sfd, sz) -- Set size of queue for waiting connections
end end
function accept(sfd) -- Accept Connection function accept(sfd) -- Accept Connection
end end
function send(sfd,...) -- Standard Network I/O function send(sfd, ...) -- Standard Network I/O
end end
function recv(sfd) -- Standard Network I/O function recv(sfd) -- Standard Network I/O
end end
function shutdown(sfd) -- Close Socket function shutdown(sfd) -- Close Socket
end end
function close(sfd) -- Close Socket function close(sfd) -- Close Socket
end
function do_dhcp_client() -- Connect to DHCP Server and try to get a tag.
end end
function do_arp_query(tag) -- ARP: Query uuid with tag, might send arp-request function do_arp_query(tag) -- ARP: Query uuid with tag, might send arp-request
local ret,uuid=_isInArpCache(tag) local ret, uuid = _isInArpCache(tag)
if(ret) then return uuid if (ret) then
return uuid
else else
local quest=_generateARPQuest(tag) local questHeader = _generateARPQuestHeader()
for i=1,3,1 do for i = 1, 3, 1 do
if(_doArpBroadcastQuery(quest)) then if (_doArpBroadcastQuery(questHeader, tag)) then
local e,etag,euuid=event.pull(0.5,"net_newarp") local e, etag, euuid = event.pull(0.5, "net_newarp")
if(e~=nil) then return euuid end if (e ~= nil and etag == tag) then
return euuid
end
end end
end end
return nil -- Failed to query arp in 3 tries. return nil -- Failed to query arp in 3 tries.
@ -194,41 +203,84 @@ function do_arp_query(tag) -- ARP: Query uuid with tag, might send arp-request
end end
function run_arp() -- Start ARP Services in background function run_arp() -- Start ARP Services in background
event.listen("modem_message", event.listen(
function(_event,_receiver,sender,_port,_distance,...) "modem_message",
if(_port==9) then function(_event, _receiver, sender, _port, _distance, ...)
if(arg[1]==string.pack("iii",1,0,0) and arg[2]~=nil) then -- Received an ARP Broadcast if (_port == 9) then
if(arpker[arg[2]]==nil) then if (arg[1] == arp_broadcast and arg[2] ~= nil) then
arpker[arg[2]]=sender -- Received an ARP Broadcast
event.push("net_newarp",arg[2],sender) if (arpker[arg[2]] == nil) then
elseif(arpker[arg[2]]~=sender) then arpker[arg[2]] = sender
arpker[arg[2]]=sender event.push("net_newarp", arg[2], sender)
event.push("net_arpchanged",arg[2],sender) elseif (arpker[arg[2]] ~= sender) then
end -- arpker check arpker[arg[2]] = sender
elseif(arg[1]==string.pack("iii",1,0,1) and arg[2]~=nil) then -- Received an ARP Quest Broadcast event.push("net_arpchanged", arg[2], sender)
//todo end -- arpker check
end -- arg1 and arg2 check elseif (arg[1] == arp_quest and arg[2] ~= nil and arg[2] == arpker.thisDevice) then
end -- port check -- Received an ARP Quest Broadcast and it points this device
end) -- callback netcard.send(sender, 9, arp_broadcast, arg[2])
end end -- arg1 and arg2 check
end -- port check
end
) -- callback
netcard.open(9)
end
function run_dhcp_client() -- Start DHCP Client in background function run_dhcp_client() -- Start DHCP Client in background
local finished = false
event.listen(
"modem_message",
function(_event, _receiver, sender, port, _distance, ...)
if (port == 8 and arg[1] == dhcp_ack) then
-- Receive DHCP Answer
arpker.thisDevice = arg[2]
-- Close Local Port
network.close(7)
-- Change flag to stop running
finished = true
-- Unregister this callback
return false
end
end
)
network.open(7)
while not finished do
network.broadcast(8, dhcp_quest)
os.sleep(1)
end
end end
function run_tcp() -- Start TCP Services in background function run_tcp() -- Start TCP Services in background
event.listen("modem_message", event.listen(
function(_event,_receiver,sender,_port,_distance...) "modem_message",
if(_port==10) then function(_event, _receiver, sender, port, _distance, ...)
if(arg[1]==string.pack("iii",1,1,1)) then --SYN if (port == 10) then
event.push("net_newsyn",sender,arg[2]) if (arg[1] == tcp_syn) then --SYN
event.push("net_newsyn", sender, arg[2])
end
elseif (port == 11) then
if (arg[1] == tcp_synack) then --SYN/ACK
event.push("net_newsynack", sender)
end
end
end
)
event.listen(
"modem_message",
function(_event, _receiver, sender, port, _distance, ...)
if (port == 12) then
if (arg[1] == trans_data and arg[2] ~= nil) then
-- Find cookie and push data
for k, t in pairs(sker.fdset) do
if (t.local_cookie == arg[2]) then
t.recvBus.push_back(arg[3])
break
end
end
end
end
end
)
netcard.open(10)
netcard.open(11)
end end
elseif(_port==11) then
if(arg[1]==string.pack("iii",1,1,3)) then --SYN/ACK
event.push("net_newsynack",sender)
end
end
end)
netcard.open(10)
netcard.open(11)
end