always discard already seen packets

This commit is contained in:
Alain Zscheile 2022-11-26 02:29:26 +01:00
parent 1bb7597803
commit ecf27c1f01

View file

@ -60,21 +60,28 @@ defmodule Floof.Distributor do
@impl true
def handle_cast({:xfer, {origin, dcdhash, dcd, attrs}}, state) do
if check_incoming(dstate(state, :fconf), dcd, attrs) do
# we split the state such that only the parts necessary get
# copied into the spawned-off process
fconf = dstate(state, :fconf)
if check_incoming(fconf, dcdhash, dcd, attrs) do
trgs = MapSet.delete(dstate(state, :trgs), origin)
Floof.DistributorSeen.mark_seen(dcdhash)
# spawn a separate process to avoid blocking the queue
# we only block the queue above for the check + seen marker
spawn_link(fn ->
{:XferBlob, source, ttl, old_markers, signature, data} = dcd
set_markers = fconfig(dstate(state, :fconf), :set_markers)
set_markers = fconfig(fconf, :set_markers)
new_markers = Enum.uniq(set_markers ++ old_markers)
dcd2 = {:XferBlob, source, ttl, new_markers, signature, data}
for trg <- MapSet.delete(dstate(state, :trgs), origin) do
for trg <- trgs do
send(trg, {:fwdxfer, {dcdhash, dcd2}})
end
Floof.SessionManager.set_for_all(dcdhash, dcd2, origin)
end)
Floof.DistributorSeen.mark_seen(dcdhash)
end
{:noreply, state}
@ -85,7 +92,7 @@ defmodule Floof.Distributor do
{:noreply, dstate(state, trgs: MapSet.delete(dstate(state, :trgs), pid))}
end
defp check_incoming(fconf, dcd, attrs) do
defp check_incoming(fconf, dcdhash, dcd, attrs) do
{:XferBlob, source, ttl, _, {:Signature, sigalgo, sigval}, xfinner} = dcd
case sigalgo do
@ -94,6 +101,10 @@ defmodule Floof.Distributor do
case get_pubkey(fconf, source) do
{:ok, :ed25519, pubkey} ->
cond do
Floof.DistributorSeen.have_we(dcdhash) ->
# we can ignore this packet, its content was already processed
false
not :enacl.sign_verify_detached(sigval, xfinner, pubkey) ->
Logger.error("packet signature invalid for #{inspect(xfinner)}")
false