diff options
Diffstat (limited to 'shard/lib/net')
-rw-r--r-- | shard/lib/net/addr.ex | 18 | ||||
-rw-r--r-- | shard/lib/net/auth.ex | 10 | ||||
-rw-r--r-- | shard/lib/net/group.ex | 12 | ||||
-rw-r--r-- | shard/lib/net/manager.ex | 12 | ||||
-rw-r--r-- | shard/lib/net/tcpconn.ex | 15 | ||||
-rw-r--r-- | shard/lib/net/tcpserver.ex | 4 |
6 files changed, 59 insertions, 12 deletions
diff --git a/shard/lib/net/addr.ex b/shard/lib/net/addr.ex index c1d2f05..b92ae70 100644 --- a/shard/lib/net/addr.ex +++ b/shard/lib/net/addr.ex @@ -1,4 +1,10 @@ defmodule SNet.Addr do + @moduledoc""" + Helper module for getting our IP addresses. + + Runs an agent that gets our public IPv4 address on the internet and stores it. + """ + use Agent require Logger @@ -21,6 +27,9 @@ defmodule SNet.Addr do end end + @doc""" + Reteurn the list of IPv4 address for our network interfaces. + """ def get_if_inet4 do {:ok, ifs} = :inet.getifaddrs for {_, opts} <- ifs, @@ -32,15 +41,24 @@ defmodule SNet.Addr do end end + @doc""" + Return our public IPv4 address as observed by an external API provider (`ipify.org`) + """ def get_pub_inet4 do Agent.get(__MODULE__, &(&1)) end + @doc""" + Get all our IPv4 addresses. + """ def get_all_inet4 do addrset = for x <- get_if_inet4() ++ get_pub_inet4(), into: %MapSet{}, do: x MapSet.to_list addrset end + @doc""" + Determines if an IP address is ours or not. + """ def is_local?({:inet, ip, port}) do port == Application.get_env(:shard, :port) and (ip == {127,0,0,1} or ip in get_all_inet4()) end diff --git a/shard/lib/net/auth.ex b/shard/lib/net/auth.ex index c903093..186b506 100644 --- a/shard/lib/net/auth.ex +++ b/shard/lib/net/auth.ex @@ -1,3 +1,13 @@ defmodule SNet.Auth do + @moduledoc""" + Structure for auth values that define if a connection is with an anonymous + peer or with an authenticated peer. + + Message handlers in shards will receive an `auth` parameter equal to `nil` if the + connection where the message comes from is not authenticated, or + `%SNet.Auth{my_pk: my_pk, his_pk: his_pk}` in the case where the connection is authenticated, + we are known to them as `my_pk` and they are known to us as `his_pk`. + """ + defstruct [:my_pk, :his_pk] end diff --git a/shard/lib/net/group.ex b/shard/lib/net/group.ex index a5f0867..f3d5962 100644 --- a/shard/lib/net/group.ex +++ b/shard/lib/net/group.ex @@ -25,11 +25,17 @@ defprotocol SNet.Group do @doc""" Check if a peer is allowed to participate in this group. + The `auth` parameter is `nil` or a `SNet.Auth` struct. """ def in_group?(group, conn_pid, auth) end defmodule SNet.PubShardGroup do + @moduledoc""" + A network group defined as all the people interested in a given shard. + + %SNet.PubShardGroup{id: shard_id} + """ defstruct [:id] defimpl SNet.Group do @@ -85,6 +91,12 @@ defmodule SNet.PubShardGroup do end defmodule SNet.PrivGroup do + @moduledoc""" + A private networking group defined by the list of public keys of people allowed to + participate. + + %SNet.PrivGroup{pk_list: [pk1, pk2, ...]} + """ defstruct [:pk_list] defimpl SNet.Group do diff --git a/shard/lib/net/manager.ex b/shard/lib/net/manager.ex index fb92f13..e4d8ad9 100644 --- a/shard/lib/net/manager.ex +++ b/shard/lib/net/manager.ex @@ -1,9 +1,8 @@ defmodule SNet.Manager do @moduledoc""" - - :connections (not persistent) + Maintains a table `:connections` of currently connected peers, which is a list of: - List of - { peer_info, pid, nil | {my_pk, his_pk} } + { peer_info, pid, nil | %SNet.Auth{my_pk: my_pk, his_pk: his_pk} } """ use GenServer @@ -91,7 +90,7 @@ defmodule SNet.Manager do @doc""" Connect to a peer specified by ip address and port - peer_info := {:inet, ip, port} + peer_info := {:inet, ip, port} """ def add_peer(peer_info, opts \\ []) do GenServer.call(__MODULE__, {:add_peer, peer_info, opts[:auth], opts[:callback]}) @@ -134,6 +133,11 @@ defmodule SNet.Manager do end end + @doc""" + Send message to a peer specified by peer info over authenticated channel. + `auth` is a `SNet.Auth` struct describing the required authentication. + Opens a connection if necessary. + """ def send_auth(peer_info, auth, msg) do case :ets.match(:connections, {peer_info, :'$1', auth, :_}) do [[pid]|_] -> diff --git a/shard/lib/net/tcpconn.ex b/shard/lib/net/tcpconn.ex index 21d25df..dc33bff 100644 --- a/shard/lib/net/tcpconn.ex +++ b/shard/lib/net/tcpconn.ex @@ -1,10 +1,9 @@ defmodule SNet.TCPConn do @moduledoc""" Secret handshake as described in this document: - https://ssbc.github.io/scuttlebutt-protocol-guide/#peer-connections + <https://ssbc.github.io/scuttlebutt-protocol-guide/#peer-connections> - Does not implement the stream protocol, we don't hide the length of packets. - (TODO ^) + TODO: Does not implement the stream protocol, we don't hide the length of packets. """ @@ -18,15 +17,15 @@ defmodule SNet.TCPConn do Expected initial state: a dict with the following keys: - - socket: the socket - - is_client: true if we are the initiator of the connection, false otherwise - - my_port: if we are the client, what port should the other dial to recontact us + - `socket`: the socket, if we are responding to a connection + - `connect_to`: the IP and port we want to connect to, if we are the initiator of the connection + - `my_port`: if we are the initiator, what port should the other dial to recontact us Optionnally, and only if we are the initiator of the connection, the following key: - - auth: nil | {my_pk, list_accepted_his_pk} + - `auth`: `nil | {my_pk, list_accepted_his_pk}` - If we are initiator of the connection, we will use crypto if and only if auth is not nil. + If we are initiator of the connection, we will use crypto if and only if auth is not `nil`. """ def start_link(state) do GenServer.start_link(__MODULE__, state) diff --git a/shard/lib/net/tcpserver.ex b/shard/lib/net/tcpserver.ex index d7326ad..827fefa 100644 --- a/shard/lib/net/tcpserver.ex +++ b/shard/lib/net/tcpserver.ex @@ -1,4 +1,8 @@ defmodule SNet.TCPServer do + @moduledoc""" + Process for accepting TCP connections from peers. + """ + require Logger use Task, restart: :permanent |