mirror of
https://github.com/XeonSquared/OC-Copper.git
synced 2024-11-23 09:58:06 +11:00
Lowered protocol packet size limit and changed how it's calculated, also changed testcase to be slightly less worst-case.
The previous testcase was "all nodes communicating randomly", basically a worst-case. This testcase is somewhat more realistic, a set of nodes communicating between each other via other nodes, a given TO node recurring once every 5 seconds (approximately). Notably, the 'packet transfer total' figure should be halved, as in the testcase pings and responses are used, but only responses are counted.
This commit is contained in:
parent
97fd892922
commit
47ec74bc89
52
culib.lua
52
culib.lua
@ -26,18 +26,18 @@ return function (hostname, transmit, onReceive, time)
|
|||||||
|
|
||||||
-- How many packets need to be stored in seenBefore's keyspace
|
-- How many packets need to be stored in seenBefore's keyspace
|
||||||
-- before 'panic' is the best response?
|
-- before 'panic' is the best response?
|
||||||
local tuningMaxSeenBeforeCountBeforeEmergencyFlush = 0x100
|
local tuningMaxSeenBeforeCountBeforeEmergencyFlush = 0x300
|
||||||
|
|
||||||
-- Expect a response by this many seconds,
|
-- Expect a response by this many seconds,
|
||||||
-- or else clear the known receivers cache and resend.
|
-- or else clear the known receivers cache and resend.
|
||||||
local tuningExpectResponse = 10
|
local tuningExpectResponse = 120
|
||||||
|
|
||||||
-- Flush the loop detector every so often.
|
-- Flush the loop detector every so often.
|
||||||
-- This is not a complete clear.
|
-- This is not a complete clear.
|
||||||
local tuningFlushLoopDetector = 10
|
local tuningFlushLoopDetector = 120
|
||||||
|
|
||||||
-- Do not change this value. I mean it. Don't. Just. Don't.
|
-- Do not change this value unless protocol has changed accordingly.
|
||||||
local tuningAutorejectLen = 4000
|
local tuningAutorejectLen = 1506
|
||||||
|
|
||||||
local loopDetectorNext = time() + tuningFlushLoopDetector
|
local loopDetectorNext = time() + tuningFlushLoopDetector
|
||||||
|
|
||||||
@ -68,10 +68,11 @@ return function (hostname, transmit, onReceive, time)
|
|||||||
seenBeforeCount = seenBeforeCount - 1
|
seenBeforeCount = seenBeforeCount - 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
loopDetectorNext = time() + tuningFlushLoopDetector
|
loopDetectorNext = t + tuningFlushLoopDetector
|
||||||
end
|
end
|
||||||
for k, v in pairs(lastKnownReceiver) do
|
for k, v in pairs(lastKnownReceiver) do
|
||||||
if t >= v[2] then
|
if t >= v[2] then
|
||||||
|
print("It was decided LKV[" .. k .. "] was out of date @ " .. v[2])
|
||||||
lastKnownReceiver[k] = nil
|
lastKnownReceiver[k] = nil
|
||||||
for _, m in ipairs(v[3]) do
|
for _, m in ipairs(v[3]) do
|
||||||
transmit(nil, m)
|
transmit(nil, m)
|
||||||
@ -86,14 +87,16 @@ return function (hostname, transmit, onReceive, time)
|
|||||||
culib.hostname = hostname
|
culib.hostname = hostname
|
||||||
culib.input = function (node, message)
|
culib.input = function (node, message)
|
||||||
local t = time()
|
local t = time()
|
||||||
if message:len() > tuningAutorejectLen then
|
|
||||||
return
|
-- Eliminate the hops value first of all.
|
||||||
end
|
local hops = message:byte(1)
|
||||||
|
message = message:sub(2)
|
||||||
|
|
||||||
if seenBefore[message] then
|
if seenBefore[message] then
|
||||||
seenBefore[message] = seenBefore[message] + 1
|
seenBefore[message] = seenBefore[message] + 1
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
seenBefore[message] = 0
|
seenBefore[message] = 2
|
||||||
seenBeforeCount = seenBeforeCount + 1
|
seenBeforeCount = seenBeforeCount + 1
|
||||||
if seenBeforeCount > tuningMaxSeenBeforeCountBeforeEmergencyFlush then
|
if seenBeforeCount > tuningMaxSeenBeforeCountBeforeEmergencyFlush then
|
||||||
-- Panic
|
-- Panic
|
||||||
@ -101,7 +104,8 @@ return function (hostname, transmit, onReceive, time)
|
|||||||
seenBefore = {}
|
seenBefore = {}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Begin parsing
|
-- Begin parsing.
|
||||||
|
|
||||||
local rawmessage = message
|
local rawmessage = message
|
||||||
|
|
||||||
if message:len() < 2 then return end
|
if message:len() < 2 then return end
|
||||||
@ -114,12 +118,34 @@ return function (hostname, transmit, onReceive, time)
|
|||||||
local tnam = message:sub(2, nlen + 1)
|
local tnam = message:sub(2, nlen + 1)
|
||||||
message = message:sub(nlen + 2)
|
message = message:sub(nlen + 2)
|
||||||
|
|
||||||
lastKnownReceiver[fnam] = {node, t + tuningExpectResponse, {}}
|
if message:len() > tuningAutorejectLen then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local restart = true
|
||||||
|
if lastKnownReceiver[fnam] then
|
||||||
|
if lastKnownReceiver[fnam][1] == node then
|
||||||
|
restart = false
|
||||||
|
-- allow frequently-used links to last longer
|
||||||
|
lastKnownReceiver[fnam][2] = lastKnownReceiver[fnam][2] + tuningExpectResponse
|
||||||
|
lastKnownReceiver[fnam][3] = {}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
end
|
||||||
|
if restart then
|
||||||
|
lastKnownReceiver[fnam] = {node, t + tuningExpectResponse, {}}
|
||||||
|
end
|
||||||
|
|
||||||
onReceive(fnam, tnam, message)
|
onReceive(fnam, tnam, message)
|
||||||
if culib.hostname == tnam then return end
|
if culib.hostname == tnam then return end
|
||||||
|
|
||||||
-- Redistribution of messages not aimed here
|
-- Redistribution of messages not aimed here
|
||||||
|
if hops == 255 then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
rawmessage = string.char(hops + 1) .. rawmessage
|
||||||
|
end
|
||||||
|
|
||||||
local lkr = lastKnownReceiver[tnam]
|
local lkr = lastKnownReceiver[tnam]
|
||||||
if lkr then
|
if lkr then
|
||||||
transmit(lkr[1], rawmessage)
|
transmit(lkr[1], rawmessage)
|
||||||
@ -137,7 +163,7 @@ return function (hostname, transmit, onReceive, time)
|
|||||||
culib.output = function (fnam, tnam, message)
|
culib.output = function (fnam, tnam, message)
|
||||||
onReceive(fnam, tnam, message)
|
onReceive(fnam, tnam, message)
|
||||||
if tnam == culib.hostname then return end
|
if tnam == culib.hostname then return end
|
||||||
local m = encodeName(fnam) .. encodeName(tnam) .. message
|
local m = "\x00" .. encodeName(fnam) .. encodeName(tnam) .. message
|
||||||
transmit(nil, m)
|
transmit(nil, m)
|
||||||
end
|
end
|
||||||
return culib
|
return culib
|
||||||
|
11
protocol.0
11
protocol.0
@ -15,14 +15,15 @@ Copper addresses are names.
|
|||||||
In the context of a system not implementing a hierarchial gateway,
|
In the context of a system not implementing a hierarchial gateway,
|
||||||
this is as much about Copper addressing as matters.
|
this is as much about Copper addressing as matters.
|
||||||
|
|
||||||
Copper base packets contain 3 fields.
|
Copper base packets contain 4 fields.
|
||||||
|
One byte indicating how many nodes have retransmitted the message
|
||||||
|
(the original sender should use 0),
|
||||||
A name (as a length-minus-1-byte-prefixed-string),
|
A name (as a length-minus-1-byte-prefixed-string),
|
||||||
another name (in the same format),
|
another name (in the same format),
|
||||||
and the rest is data.
|
and the rest is data.
|
||||||
|
|
||||||
Copper packets may be up to 4000 bytes long, including base.
|
Copper packet data may be up to 1506 bytes long -
|
||||||
(It's assumed the additional 96 bytes will be useful for any additional
|
this does not include header data, which may be up to (256*2) + 3 bytes long.
|
||||||
framing, assuming a 4K packet limit.)
|
|
||||||
|
|
||||||
Loop detection should performed by checking if a packet exactly the same has
|
Loop detection should performed by checking if a packet exactly the same has
|
||||||
been seen recently - other rejection, alteration and routing measures
|
been seen recently - other rejection, alteration and routing measures
|
||||||
@ -36,4 +37,4 @@ Should a situation be dire enough,
|
|||||||
hierarchial networks (described in file 2, 'protocol.1'),
|
hierarchial networks (described in file 2, 'protocol.1'),
|
||||||
and custom routing software in general,
|
and custom routing software in general,
|
||||||
can be used to split networks however the system requires.
|
can be used to split networks however the system requires.
|
||||||
Copper isn't very picky.
|
|
||||||
|
@ -8,8 +8,7 @@ They are simply base low-level Copper nodes with two interfaces and the
|
|||||||
|
|
||||||
For the FROM address:
|
For the FROM address:
|
||||||
|
|
||||||
If it's on the parent side, reject if it's prefixed with hostname ..
|
If it's on the parent side, reject if it's prefixed with hostname .. "/",
|
||||||
"/",
|
|
||||||
otherwise prefix it with "<" and forward to child side.
|
otherwise prefix it with "<" and forward to child side.
|
||||||
If it's on the child side, reject if it's prefixed with "<",
|
If it's on the child side, reject if it's prefixed with "<",
|
||||||
otherwise prefix it with hostname .. "/" and forward to parent side.
|
otherwise prefix it with hostname .. "/" and forward to parent side.
|
||||||
|
@ -17,15 +17,14 @@ All implementations of Copper that synthesize their own packets SHOULD
|
|||||||
follow this protocol when doing so, unless they are a custom system
|
follow this protocol when doing so, unless they are a custom system
|
||||||
that will not be connected to any global network.
|
that will not be connected to any global network.
|
||||||
|
|
||||||
|
|
||||||
Firstly, note that, to the application, a Reliability Layer packet can
|
Firstly, note that, to the application, a Reliability Layer packet can
|
||||||
be up to 59,895 bytes in size, though a fragment can only be up to 3993 bytes.
|
be up to 22,500 bytes in size, though a fragment can only be up to 1500 bytes.
|
||||||
|
|
||||||
Secondly, note that an application should be able to ask to be notified
|
Secondly, note that an application should be able to ask to be notified
|
||||||
when a packet is received successfully or when the implementation gives up,
|
when a packet is received successfully or when the implementation gives up,
|
||||||
with a flag indicating which is which.
|
with a flag indicating which is which.
|
||||||
|
|
||||||
Reliability Layer packets have a simple format.
|
Reliability Layer packets have a simple 6-byte header.
|
||||||
The first two bytes are the port number, in big-endian format.
|
The first two bytes are the port number, in big-endian format.
|
||||||
The next three bytes are a number to this application-side packet.
|
The next three bytes are a number to this application-side packet.
|
||||||
They should be as random as possible.
|
They should be as random as possible.
|
||||||
|
23
runtest.lua
23
runtest.lua
@ -7,7 +7,7 @@ local nodenames = {}
|
|||||||
|
|
||||||
local systime = 0
|
local systime = 0
|
||||||
local function getsystime()
|
local function getsystime()
|
||||||
return systime / 20
|
return systime / 10
|
||||||
end
|
end
|
||||||
|
|
||||||
local queuedCalls = {}
|
local queuedCalls = {}
|
||||||
@ -58,13 +58,24 @@ end)
|
|||||||
|
|
||||||
-- Start testing
|
-- Start testing
|
||||||
|
|
||||||
|
local targetables = {}
|
||||||
|
local targetableCount = 10
|
||||||
|
for i = 1, targetableCount do
|
||||||
|
targetables[i] = math.random(#nodes)
|
||||||
|
end
|
||||||
|
|
||||||
local function generateMessage()
|
local function generateMessage()
|
||||||
local na = math.random(#nodes)
|
local na = 1
|
||||||
local nb = math.random(#nodes)
|
local nb = 1
|
||||||
|
while na == nb do
|
||||||
|
na = targetables[math.random(#targetables)]
|
||||||
|
nb = targetables[math.random(#targetables)]
|
||||||
|
end
|
||||||
nodes[na].output(nodenames[na], nodenames[nb], "T" .. tostring(math.random()))
|
nodes[na].output(nodenames[na], nodenames[nb], "T" .. tostring(math.random()))
|
||||||
end
|
end
|
||||||
|
|
||||||
local generateEvery = 1
|
-- ~Once every 5 seconds, think a polling script
|
||||||
|
local generateEvery = math.floor(50 / targetableCount)
|
||||||
local generateCount = 10000
|
local generateCount = 10000
|
||||||
while (generateCount > 0) or (#queuedCalls > 0) do
|
while (generateCount > 0) or (#queuedCalls > 0) do
|
||||||
if (systime % generateEvery) == 0 then
|
if (systime % generateEvery) == 0 then
|
||||||
@ -81,8 +92,8 @@ while (generateCount > 0) or (#queuedCalls > 0) do
|
|||||||
for _, v in ipairs(qc) do
|
for _, v in ipairs(qc) do
|
||||||
v()
|
v()
|
||||||
end
|
end
|
||||||
print("run iteration, " .. #qc .. " calls")
|
--print("run iteration, " .. #qc .. " calls")
|
||||||
systime = systime + 1
|
systime = systime + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
print(statSD, statPT)
|
print(#nodes, statSD, statPT)
|
||||||
|
Loading…
Reference in New Issue
Block a user