Skip to content

Commit 193a38c

Browse files
authored
Update example and ex_stun (#10)
1 parent 268ee0a commit 193a38c

File tree

9 files changed

+101
-30
lines changed

9 files changed

+101
-30
lines changed

.formatter.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Used by "mix format"
22
[
3-
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test, example}/**/*.{ex,exs}"]
44
]

example/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Simple ICE Example
2+
3+
Run as:
4+
5+
```bash
6+
elixir peer.exs <signalling-ip> <signalling-port>
7+
```
8+
9+
`signalling-ip` defaults to 127.0.0.1
10+
`signalling-port` defaults to 4000
11+
12+
You can use our simple [signalling server](../signalling_server)
13+
14+
## Protocol
15+
16+
peer.exs sends following messages:
17+
18+
* `credentials`
19+
20+
```json
21+
{
22+
"type": "credentials",
23+
"ufrag": "someufrag",
24+
"passwd": "somepasswd"
25+
}
26+
```
27+
28+
* `candidate`
29+
30+
```json
31+
{
32+
"type": "candidate",
33+
"cand": "somecandidate"
34+
}
35+
```
36+
37+
* `end_of_candidates`
38+
39+
```json
40+
{
41+
"type": "end_of_candidates"
42+
}
43+
```
44+
45+

example/peer.exs

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
Mix.install([{:gun, "~> 2.0.1"}, {:ex_ice, path: "../"}, {:jason, "~> 1.4.0"}])
1+
Mix.install([{:gun, "~> 2.0.1"}, {:ex_ice, path: "../", force: true}, {:jason, "~> 1.4.0"}])
2+
3+
require Logger
4+
Logger.configure(level: :info)
25

36
defmodule Peer do
47
use GenServer
@@ -31,7 +34,8 @@ defmodule Peer do
3134
receive do
3235
{:gun_upgrade, ^conn, stream, _, _} ->
3336
Logger.info("Connected to the signalling server")
34-
{:ok, %{conn: conn, stream: stream, ice: nil}}
37+
Process.send_after(self(), :ws_ping, 1000)
38+
{:ok, %{conn: conn, stream: stream, ice: nil, timer: nil}}
3539

3640
other ->
3741
Logger.error("Couldn't connect to the signalling server: #{inspect(other)}")
@@ -48,21 +52,41 @@ defmodule Peer do
4852
{:stop, :normal, state}
4953
end
5054

55+
@impl true
56+
def handle_info(:ws_ping, state) do
57+
Process.send_after(self(), :ws_ping, 1000)
58+
:gun.ws_send(state.conn, state.stream, :ping)
59+
{:noreply, state}
60+
end
61+
5162
@impl true
5263
def handle_info({:gun_ws, _, _, {:text, msg}}, state) do
5364
state = handle_ws_msg(Jason.decode!(msg), state)
5465
{:noreply, state}
5566
end
5667

68+
@impl true
69+
def handle_info({:gun_ws, _, _, {:close, code}}, _state) do
70+
Logger.info("Signalling connection closed with code: #{code}. Exiting")
71+
exit(:ws_down)
72+
end
73+
5774
@impl true
5875
def handle_info({:ex_ice, _pid, msg}, state) do
5976
state = handle_ice_msg(msg, state)
6077
{:noreply, state}
6178
end
6279

80+
@impl true
81+
def handle_info(:send_ping, state) do
82+
ref = Process.send_after(self(), :send_ping, 1000)
83+
:ok = ICEAgent.send_data(state.ice, "ping")
84+
{:noreply, %{state | timer: ref}}
85+
end
86+
6387
@impl true
6488
def handle_info(msg, state) do
65-
Logger.warn("Received unknown msg: #{inspect(msg)}")
89+
Logger.warning("Received unknown msg: #{inspect(msg)}")
6690
{:noreply, state}
6791
end
6892

@@ -79,14 +103,17 @@ defmodule Peer do
79103
stun_servers: ["stun:stun.l.google.com:19302"]
80104
)
81105

82-
:ok = ICEAgent.run(pid)
106+
{:ok, ufrag, passwd} = ICEAgent.get_local_credentials(pid)
107+
108+
msg = %{type: "credentials", ufrag: ufrag, passwd: passwd} |> Jason.encode!()
109+
:gun.ws_send(state.conn, state.stream, {:text, msg})
110+
111+
:ok = ICEAgent.gather_candidates(pid)
83112
%{state | ice: pid}
84113
end
85114

86115
defp handle_ws_msg(%{"type" => "credentials", "ufrag" => ufrag, "passwd" => passwd}, state) do
87-
:ok =
88-
ICEAgent.set_remote_credentials(state.ice, Base.decode64!(ufrag), Base.decode64!(passwd))
89-
116+
:ok = ICEAgent.set_remote_credentials(state.ice, ufrag, passwd)
90117
state
91118
end
92119

@@ -100,34 +127,33 @@ defmodule Peer do
100127
state
101128
end
102129

103-
def handle_ice_msg({:local_credentials, ufrag, passwd}, state) do
104-
msg =
105-
%{type: "credentials", ufrag: Base.encode64(ufrag), passwd: Base.encode64(passwd)}
106-
|> Jason.encode!()
107-
108-
:gun.ws_send(state.conn, state.stream, {:text, msg})
109-
state
110-
end
111-
112130
def handle_ice_msg({:new_candidate, cand}, state) do
131+
113132
msg = %{type: "candidate", cand: cand} |> Jason.encode!()
114133
:gun.ws_send(state.conn, state.stream, {:text, msg})
115134
state
116135
end
117136

118-
def handle_ice_msg(:gathering_complete, state) do
137+
def handle_ice_msg({:gathering_state_change, :complete} = msg, state) do
138+
Logger.info("ICE: #{inspect(msg)}")
119139
msg = %{type: "end_of_candidates"} |> Jason.encode!()
120140
:gun.ws_send(state.conn, state.stream, {:text, msg})
121141
state
122142
end
123143

144+
def handle_ice_msg(:completed, state) do
145+
Logger.info("ICE: :completed")
146+
Logger.info("Starting sending...")
147+
ref = Process.send_after(self(), :send_ping, 1000)
148+
%{state | timer: ref}
149+
end
150+
124151
def handle_ice_msg(other, state) do
125152
Logger.info("ICE: #{inspect(other)}")
126153
state
127154
end
128155
end
129156

130-
require Logger
131157

132158
{:ok, pid} = Peer.start_link()
133159
ref = Process.monitor(pid)
@@ -137,5 +163,5 @@ receive do
137163
Logger.info("Peer process closed. Exiting")
138164

139165
other ->
140-
Logger.warn("Unexpected msg. Exiting. Msg: #{inspect(other)}")
166+
Logger.warning("Unexpected msg. Exiting. Msg: #{inspect(other)}")
141167
end

lib/ice_agent.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ defmodule ExICE.ICEAgent do
339339
def handle_info(:ta_timeout, %{remote_ufrag: nil, remote_pwd: nil} = state) do
340340
# TODO we can do this better i.e.
341341
# allow for executing gathering transactions
342+
Logger.debug("Ta timer fired but there are no remote credentials. Scheduling next check")
342343
ta_timer = Process.send_after(self(), :ta_timeout, @ta_timeout)
343344
state = %{state | ta_timer: ta_timer}
344345
state = update_ta_timer(state)
@@ -781,7 +782,7 @@ defmodule ExICE.ICEAgent do
781782
state = put_in(state, [:checklist, conn_check_pair.id], conn_check_pair)
782783
@conn_check_handler[state.role].update_nominated_flag(state, pair_id, nominate?)
783784
else
784-
{:error, reason} when reason in [:invalid_message_integrity, :invalid_fingerprint] ->
785+
{:error, reason} when reason == :invalid_auth_attributes ->
785786
Logger.debug("Ignoring conn check response, reason: #{reason}")
786787

787788
conn_check_pair = %CandidatePair{conn_check_pair | state: :failed}
@@ -1276,11 +1277,10 @@ defmodule ExICE.ICEAgent do
12761277

12771278
defp authenticate_msg(msg, local_pwd) do
12781279
with {:ok, key} <- Message.authenticate_st(msg, local_pwd),
1279-
true <- Message.check_fingerprint(msg) do
1280+
:ok <- Message.check_fingerprint(msg) do
12801281
{:ok, key}
12811282
else
1282-
:error -> {:error, :invalid_message_integrity}
1283-
false -> {:error, :invalid_fingerprint}
1283+
{:error, _reason} -> {:error, :invalid_auth_attributes}
12841284
end
12851285
end
12861286

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ defmodule ExICE.MixProject do
2929

3030
defp deps do
3131
[
32-
{:ex_stun, github: "elixir-webrtc/ex_stun"},
32+
{:ex_stun, "~> 0.1.0"},
3333
{:excoveralls, "~> 0.14.6", only: :test, runtime: false},
3434
{:ex_doc, "~> 0.27", only: :dev, runtime: false},
3535
{:credo, "~> 1.6", only: [:dev, :test], runtime: false}

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"credo": {:hex, :credo, "1.6.5", "330ca591c12244ab95498d8f47994c493064b2689febf1236d43d596b4f2261d", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "101de53e6907397c3246ccd2cc9b9f0d3fc0b7805b8e1c1c3d818471fc85bafd"},
55
"earmark_parser": {:hex, :earmark_parser, "1.4.26", "f4291134583f373c7d8755566122908eb9662df4c4b63caa66a0eabe06569b0a", [:mix], [], "hexpm", "48d460899f8a0c52c5470676611c01f64f3337bad0b26ddab43648428d94aabc"},
66
"ex_doc": {:hex, :ex_doc, "0.28.4", "001a0ea6beac2f810f1abc3dbf4b123e9593eaa5f00dd13ded024eae7c523298", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bf85d003dd34911d89c8ddb8bda1a958af3471a274a4c2150a9c01c78ac3f8ed"},
7-
"ex_stun": {:git, "https://github.com/elixir-webrtc/ex_stun.git", "2feefe6f06135666404020e86324b5a715c0eaa1", []},
7+
"ex_stun": {:hex, :ex_stun, "0.1.0", "252474bf4c8519fbf4bc0fbfc6a1b846a634b1478c65dbbfb4b6ab4e33c2a95a", [:mix], [], "hexpm", "629fc8be45b624a92522f81d85ba001877b1f0745889a2419bdb678790d7480c"},
88
"excoveralls": {:hex, :excoveralls, "0.14.6", "610e921e25b180a8538229ef547957f7e04bd3d3e9a55c7c5b7d24354abbba70", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "0eceddaa9785cfcefbf3cd37812705f9d8ad34a758e513bb975b081dce4eb11e"},
99
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
1010
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},

signalling_server/lib/peer_handler.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ defmodule SignallingServer.PeerHandler do
2020
end
2121

2222
def handle_info(msg, state) do
23-
Logger.warn("Unknown msg: #{inspect(msg)}")
23+
Logger.warning("Unknown msg: #{inspect(msg)}")
2424
{:ok, state}
2525
end
2626

signalling_server/lib/room.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ defmodule SignallingServer.Room do
5151
if state.p2 do
5252
send(state.p2, {:forward, msg})
5353
else
54-
Logger.warn("Not forwarding msg as there is no p2")
54+
Logger.warning("Not forwarding msg as there is no p2")
5555
end
5656

5757
{:reply, :ok, state}
@@ -62,7 +62,7 @@ defmodule SignallingServer.Room do
6262
if state.p1 do
6363
send(state.p1, {:forward, msg})
6464
else
65-
Logger.warn("Not forwarding msg as there is no p1")
65+
Logger.warning("Not forwarding msg as there is no p1")
6666
end
6767

6868
{:reply, :ok, state}

signalling_server/lib/router.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ defmodule SignallingServer.Router do
1717

1818
get "/websocket" do
1919
conn
20-
|> WebSockAdapter.upgrade(SignallingServer.PeerHandler, [], timeout: 60_000)
20+
|> WebSockAdapter.upgrade(SignallingServer.PeerHandler, [], timeout: 2_000)
2121
|> halt()
2222
end
2323

0 commit comments

Comments
 (0)