# ExSTUN
[![codecov](https://codecov.io/gh/elixir-webrtc/ex_stun/branch/master/graph/badge.svg?token=7FJ64MDD0J)](https://codecov.io/gh/elixir-webrtc/ex_stun)
Implementation of STUN protocol - [RFC 8489](https://datatracker.ietf.org/doc/html/rfc8489)
## Installation
```elixir
def deps do
[
{:ex_stun, "~> 0.1.0"}
]
end
```
## Usage
```elixir
alias ExSTUN.Message
alias ExSTUN.Message.Type
alias ExSTUN.Message.Attribute.XORMappedAddress
{:ok, socket} = :gen_udp.open(0, [{:active, false}, :binary])
req =
%Type{class: :request, method: :binding}
|> Message.new()
|> Message.encode()
:ok = :gen_udp.send(socket, 'stun.l.google.com', 19302, req)
{:ok, {_, _, resp}} = :gen_udp.recv(socket, 0)
{:ok, msg} = Message.decode(resp)
Message.get_attribute(msg, XORMappedAddress)
```
## Benchmarks
```
Operating System: Linux
CPU Information: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
Number of Available Cores: 6
Available memory: 15.55 GB
Elixir 1.14.2
Erlang 25.1
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 2 s
reduction time: 2 s
parallel: 1
inputs: none specified
Estimated total run time: 3.30 min
Benchmarking binding_request.decode ...
Benchmarking binding_request.encode ...
Benchmarking binding_response.decode ...
Benchmarking binding_response.encode ...
Benchmarking error_code.from_raw ...
Benchmarking error_code.to_raw ...
Benchmarking message_full.authenticate_lt ...
Benchmarking message_full.authenticate_st ...
Benchmarking message_full.check_fingerprint ...
Benchmarking message_full.decode ...
Benchmarking message_full.encode ...
Benchmarking raw_attr.encode ...
Benchmarking software.from_raw ...
Benchmarking software.to_raw ...
Benchmarking type.from_value ...
Benchmarking type.to_value ...
Benchmarking xor_mapped_address.from_raw ...
Benchmarking xor_mapped_address.to_raw ...
Name ips average deviation median 99th %
type.to_value 10.36 M 96.49 ns ±21841.52% 82 ns 85 ns
software.to_raw 9.27 M 107.92 ns ±18500.54% 88 ns 127 ns
software.from_raw 9.09 M 109.98 ns ±10619.86% 93 ns 146 ns
raw_attr.encode 5.52 M 181.24 ns ±20597.53% 134 ns 151 ns
error_code.to_raw 5.33 M 187.68 ns ±18721.74% 131 ns 173 ns
error_code.from_raw 5.24 M 190.85 ns ±21761.54% 133 ns 188 ns
xor_mapped_address.from_raw 4.26 M 234.63 ns ±20120.48% 139 ns 404 ns
type.from_value 3.52 M 284.43 ns ±16103.68% 203 ns 345 ns
xor_mapped_address.to_raw 3.32 M 301.39 ns ±15498.33% 224 ns 280 ns
binding_request.decode 2.55 M 391.79 ns ±8498.86% 312 ns 562 ns
message_full.check_fingerprint 2.44 M 410.01 ns ±8473.68% 321 ns 568 ns
binding_response.decode 1.91 M 522.90 ns ±7523.76% 419 ns 743 ns
binding_response.encode 1.51 M 661.60 ns ±4805.20% 536 ns 830 ns
message_full.decode 0.93 M 1069.54 ns ±2911.76% 943 ns 1285 ns
binding_request.encode 0.74 M 1353.22 ns ±1471.32% 1268 ns 1510 ns
message_full.authenticate_st 0.38 M 2624.01 ns ±938.16% 2325 ns 3347 ns
message_full.encode 0.22 M 4590.41 ns ±382.62% 3880 ns 6658 ns
message_full.authenticate_lt 0.182 M 5505.80 ns ±331.43% 4992 ns 7209.08 ns
Extended statistics:
Name minimum maximum sample size mode
type.to_value 77 ns 53061243 ns 10.88 M 82 ns
software.to_raw 82 ns 53144998 ns 10.48 M 86 ns
software.from_raw 88 ns 25514683 ns 10.09 M 92 ns
raw_attr.encode 128 ns 74961546 ns 9.52 M 134 ns
error_code.to_raw 121 ns 74838686 ns 9.54 M 130 ns
error_code.from_raw 123 ns 71867196 ns 9.47 M 133 ns
xor_mapped_address.from_raw 131 ns 74689484 ns 9.00 M 138 ns
type.from_value 191 ns 70955773 ns 8.15 M 201 ns
xor_mapped_address.to_raw 211 ns 71053082 ns 7.87 M 224 ns
binding_request.decode 296 ns 51298433 ns 6.98 M 310 ns
message_full.check_fingerprint 308 ns 59012006 ns 6.64 M 318 ns
binding_response.decode 394 ns 48415319 ns 5.96 M 414 ns
binding_response.encode 519 ns 36950899 ns 5.04 M 535 ns
message_full.decode 860 ns 29238503 ns 3.61 M 927 ns
binding_request.encode 1227 ns 19876704 ns 2.95 M 1267 ns
message_full.authenticate_st 2236 ns 14685021 ns 1.68 M 2309 ns
message_full.encode 3688 ns 7095523 ns 1.00 M 3848 ns
message_full.authenticate_lt 4837 ns 6284531 ns 844.69 K 4973 ns, 4968 ns
Memory usage statistics:
Name Memory usage
type.to_value 0 B
software.to_raw 80 B - ∞ x memory usage +80 B
software.from_raw 88 B - ∞ x memory usage +88 B
raw_attr.encode 32 B - ∞ x memory usage +32 B
error_code.to_raw 112 B - ∞ x memory usage +112 B
error_code.from_raw 176 B - ∞ x memory usage +176 B
xor_mapped_address.from_raw 312 B - ∞ x memory usage +312 B
type.from_value 416 B - ∞ x memory usage +416 B
xor_mapped_address.to_raw 264 B - ∞ x memory usage +264 B
binding_request.decode 752 B - ∞ x memory usage +752 B
message_full.check_fingerprint 256 B - ∞ x memory usage +256 B
binding_response.decode 1160 B - ∞ x memory usage +1160 B
binding_response.encode 832 B - ∞ x memory usage +832 B
message_full.decode 3192 B - ∞ x memory usage +3192 B
binding_request.encode 432 B - ∞ x memory usage +432 B
message_full.authenticate_st 736 B - ∞ x memory usage +736 B
message_full.encode 2664 B - ∞ x memory usage +2664 B
message_full.authenticate_lt 1448 B - ∞ x memory usage +1448 B
**All measurements for memory usage were the same**
Reduction count statistics:
Name Reduction count
type.to_value 5
software.to_raw 1 - 0.20x reduction count -4
software.from_raw 3 - 0.60x reduction count -2
raw_attr.encode 1 - 0.20x reduction count -4
error_code.to_raw 3 - 0.60x reduction count -2
error_code.from_raw 3 - 0.60x reduction count -2
xor_mapped_address.from_raw 11 - 2.20x reduction count +6
type.from_value 6 - 1.20x reduction count +1
xor_mapped_address.to_raw 7 - 1.40x reduction count +2
binding_request.decode 11 - 2.20x reduction count +6
message_full.check_fingerprint 43 - 8.60x reduction count +38
binding_response.decode 17 - 3.40x reduction count +12
binding_response.encode 37 - 7.40x reduction count +32
message_full.decode 56 - 11.20x reduction count +51
binding_request.encode 21 - 4.20x reduction count +16
message_full.authenticate_st 60 - 12.00x reduction count +55
message_full.encode 108 - 21.60x reduction count +103
message_full.authenticate_lt 113 - 22.60x reduction count +108
**All measurements for reduction count were the same**
```