always discard already seen packets
This commit is contained in:
parent
1bb7597803
commit
ecf27c1f01
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue