aboutsummaryrefslogtreecommitdiff
path: root/shard/lib/net
diff options
context:
space:
mode:
Diffstat (limited to 'shard/lib/net')
-rw-r--r--shard/lib/net/addr.ex18
-rw-r--r--shard/lib/net/auth.ex10
-rw-r--r--shard/lib/net/group.ex12
-rw-r--r--shard/lib/net/manager.ex12
-rw-r--r--shard/lib/net/tcpconn.ex15
-rw-r--r--shard/lib/net/tcpserver.ex4
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