From 062faf49cbd98fc7ef68f8387a18c5a0a131025e Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Wed, 10 Oct 2018 17:24:00 +0200 Subject: Fixes, and I think it works not too bad at the moment. --- shard/lib/app/identity.ex | 2 +- shard/lib/application.ex | 2 + shard/lib/keys.ex | 9 ++-- shard/lib/manager.ex | 52 ++++++++++++---------- shard/lib/net/tcpconn.ex | 4 +- .../lib/shard_web/templates/page/index.html.eex | 9 ++-- shardweb/lib/shard_web/views/page_view.ex | 4 +- 7 files changed, 45 insertions(+), 37 deletions(-) diff --git a/shard/lib/app/identity.ex b/shard/lib/app/identity.ex index de39c6d..6909ad3 100644 --- a/shard/lib/app/identity.ex +++ b/shard/lib/app/identity.ex @@ -105,7 +105,7 @@ defmodule SApp.Identity do {true, st2} -> Shard.Manager.save_state(state.id, st2) state = put_in(state.state, st2) - bcast_state(state, [conn_pid]) + bcast_state(state, [GenServer.call(conn_pid, :get_peer_info)]) state {false, _} -> state diff --git a/shard/lib/application.ex b/shard/lib/application.ex index 9c1577a..6e2c7d5 100644 --- a/shard/lib/application.ex +++ b/shard/lib/application.ex @@ -16,6 +16,8 @@ defmodule Shard.Application do # Define workers and child supervisors to be supervised children = [ Shard.Keys, + { Task, fn -> Shard.Keys.get_any_identity end }, + { DynamicSupervisor, strategy: :one_for_one, name: Shard.DynamicSupervisor }, # Networking diff --git a/shard/lib/keys.ex b/shard/lib/keys.ex index d021242..b810078 100644 --- a/shard/lib/keys.ex +++ b/shard/lib/keys.ex @@ -71,7 +71,7 @@ defmodule Shard.Keys do def sign(pk, bin) do case :dets.lookup @key_db, pk do [{^pk, sk}] -> - :enacl.sign(bin, sk) + {:ok, :enacl.sign(bin, sk)} _ -> {:error, :not_found} end end @@ -114,7 +114,7 @@ defmodule Shard.Keys do def sign_detached(pk, bin) do case :dets.lookup @key_db, pk do [{^pk, sk}] -> - :enacl.sign_detached(bin, sk) + {:ok, :enacl.sign_detached(bin, sk)} _ -> {:error, :not_found} end end @@ -126,7 +126,10 @@ defmodule Shard.Keys do """ def verify(pk, bin, sign) do if valid_identity_pk? pk do - :enacl.sign_verify_detached(sign, bin, pk) + case :enacl.sign_verify_detached(sign, bin, pk) do + {:ok, _} -> :ok + err -> err + end else {:error, :invalid_pk_suffix} end diff --git a/shard/lib/manager.ex b/shard/lib/manager.ex index dd602bf..3f5416d 100644 --- a/shard/lib/manager.ex +++ b/shard/lib/manager.ex @@ -51,10 +51,11 @@ defmodule Shard.Manager do - :outbox (not persistent) Multi-list of - { dest, auth_info, message, time_inserted } + { dest_peer_info, message, time_inserted } dest := peer_info - auth_info := nil | { his_pk, my_pk_list } + + No support for messages on authenticated channels """ @@ -137,11 +138,11 @@ defmodule Shard.Manager do id_list = (for [{id, _, _}] <- :dets.match(@shard_db, :"$1"), do: id) GenServer.cast(pid, {:send_msg, {:interested, id_list}}) - # # Send queued messages - # for {_, msg, _} <- :ets.lookup(state.outbox, pk) do - # GenServer.cast(pid, {:send_msg, msg}) - # end - # :ets.delete(state.outbox, pk) + # Send queued messages + for {_, msg, _} <- :ets.lookup(state.outbox, peer_info) do + GenServer.cast(pid, {:send_msg, msg}) + end + :ets.delete(state.outbox, peer_info) {:noreply, state} end @@ -151,19 +152,17 @@ defmodule Shard.Manager do {:noreply, state} end - # def handle_cast({:connect_and_send, peer_id, msg}, state) do - # case :dets.lookup(@peer_db, peer_id) do - # [{^peer_id, nil, ip, port}] -> - # add_peer(ip, port, state) - # currtime = System.os_time :second - # :ets.insert(state.outbox, {peer_id, msg, currtime}) - # outbox_cleanup = [ {{:_, :_, :'$1'}, [{:<, :'$1', currtime - 60}], [true]} ] - # :ets.select_delete(state.outbox, outbox_cleanup) - # _ -> - # Logger.info "Dropping message #{inspect msg} for peer #{inspect peer_id}: peer not in database" - # end - # {:noreply, state} - # end + def handle_cast({:connect_and_send, peer_info, msg}, state) do + case peer_info do + {:tcp4, ip, port} -> + add_peer(ip, port, state) + currtime = System.os_time :second + :ets.insert(state.outbox, {peer_info, msg, currtime}) + outbox_cleanup = [ {{:_, :_, :'$1'}, [{:<, :'$1', currtime - 60}], [true]} ] + :ets.select_delete(state.outbox, outbox_cleanup) + end + {:noreply, state} + end def handle_cast({:try_connect, pk_list}, state) do for pk <- pk_list do @@ -249,8 +248,13 @@ defmodule Shard.Manager do Send message to a peer specified by peer info. Opens a connection if necessary. """ - def send(_peer_info, _msg) do - # TODO + def send(peer_info, msg) do + case :ets.lookup(:connections, peer_info) do + [{^peer_info, pid, _auth}|_] -> + GenServer.cast(pid, {:send_msg, msg}) + [] -> + GenServer.cast(__MODULE__, {:connect_and_send, peer_info, msg}) + end end @doc""" @@ -273,7 +277,7 @@ defmodule Shard.Manager do Return the list of all peer info for peers that are interested in a certain shard """ def get_shard_peers(shard_id) do - for [x] <- :dets.match(@peer_db, {shard_id, :"$1"}), do: x + for {_, peer_info} <- :dets.lookup(@peer_db, shard_id), do: peer_info end @doc""" @@ -326,6 +330,6 @@ defmodule Shard.Manager do Return the list of all connected peers """ def list_connections() do - for [x] <- :dets.match(:connections, :"$1"), do: x + for [x] <- :ets.match(:connections, :"$1"), do: x end end diff --git a/shard/lib/net/tcpconn.ex b/shard/lib/net/tcpconn.ex index aaab9e1..5dbf42b 100644 --- a/shard/lib/net/tcpconn.ex +++ b/shard/lib/net/tcpconn.ex @@ -118,7 +118,7 @@ defmodule SNet.TCPConn do {:ok, srv_accept} = :gen_tcp.recv(socket, 0) key4 = :crypto.hash(:sha256, net_key <> sh_sec_ab <> sh_sec_aB <> sh_sec_Ab) {:ok, det_sign_B} = :enacl.secretbox_open(srv_accept, <<0 :: 24*8>>, key4) - true = :enacl.sign_verify_detached(det_sign_B, net_key <> det_sign_A <> cli_longterm_pk <> :crypto.hash(:sha256, sh_sec_ab), srv_longterm_pk) + {:ok, _} = :enacl.sign_verify_detached(det_sign_B, net_key <> det_sign_A <> cli_longterm_pk <> :crypto.hash(:sha256, sh_sec_ab), srv_longterm_pk) # Derive secrets and initial nonces for stream communication secret_common = :crypto.hash(:sha256, :crypto.hash(:sha256, net_key <> sh_sec_ab <> sh_sec_aB <> sh_sec_Ab)) @@ -219,7 +219,7 @@ defmodule SNet.TCPConn do 96 = byte_size cli_auth_plain det_sign_A = :binary.part(cli_auth_plain, 0, 64) cli_longterm_pk = :binary.part(cli_auth_plain, 64, 32) - true = :enacl.sign_verify_detached(det_sign_A, net_key <> srv_longterm_pk <> :crypto.hash(:sha256, sh_sec_ab), cli_longterm_pk) + {:ok, _} = :enacl.sign_verify_detached(det_sign_A, net_key <> srv_longterm_pk <> :crypto.hash(:sha256, sh_sec_ab), cli_longterm_pk) # Shared secret derivation sh_sec_Ab = :enacl.curve25519_scalarmult(srv_eph_sk, :enacl.crypto_sign_ed25519_public_to_curve25519(cli_longterm_pk)) diff --git a/shardweb/lib/shard_web/templates/page/index.html.eex b/shardweb/lib/shard_web/templates/page/index.html.eex index 2efa030..efa651b 100644 --- a/shardweb/lib/shard_web/templates/page/index.html.eex +++ b/shardweb/lib/shard_web/templates/page/index.html.eex @@ -6,13 +6,12 @@ Address Port - <%= for {id, pid, ip, port} <- peer_list() do %> + <%= for {{:tcp4, ip, port}, pid, auth} <- conn_list() do %> - <%= if pid == nil do %> - <%= peer_id_to_str(id) %> - <% else %> - <%= peer_id_to_str(id) %> + <%= case auth do %> + <% nil -> %>(anonymous) + <% %SNet.Auth{his_pk: his_pk} -> %> <%= his_pk %> <% end %> <%= :inet_parse.ntoa(ip) %> diff --git a/shardweb/lib/shard_web/views/page_view.ex b/shardweb/lib/shard_web/views/page_view.ex index 533c9e5..99df99d 100644 --- a/shardweb/lib/shard_web/views/page_view.ex +++ b/shardweb/lib/shard_web/views/page_view.ex @@ -1,8 +1,8 @@ defmodule ShardWeb.PageView do use ShardWeb, :view - def peer_list do - Shard.Manager.list_peers + def conn_list do + Shard.Manager.list_connections end def peer_id_to_str(id) do -- cgit v1.2.3