esl / jerboa Goto Github PK
View Code? Open in Web Editor NEWSTUN/TURN encoder, decoder and client library in Elixir
Home Page: https://www.erlang-solutions.com/products/mongooseim.html
License: Other
STUN/TURN encoder, decoder and client library in Elixir
Home Page: https://www.erlang-solutions.com/products/mongooseim.html
License: Other
We need SEND to be able to send data from peer to client.
Right now there are not validations, so passing bad arguments results in crash of client process in most cases. We could also look into narrowing the scope of Client.ip
, or create the new type for IPv4 addresses, because we don't support IPv6 TURN extension (yet?).
Jerboa.Format.decode/1
returns various errors wrapped in a {:error, _}
tuple, and Jerboa.Format.decode!/1
raises them. However these errors are not documented, so the only way to know what is wrong is to either read an error message or name of exception struct.
It would be nice to have each of errors documented, when they are raised etc. In addition we could improve typespecs of functions which may return those errors.
@Dzol @michalwski thoughts?
As in #36
Refer to #40
Right now all attributes are represented as (e.g.):
%Attribute{
name: XORMappedAddress,
value: %XORMappedAddress{...}
}
which adds unnecessary complexity, because name of attribute could be easily taken out of value struct. My idea is to get rid of Attribute
wrapper completely.
While I was working with Jerboa on other project, I've found out that we log every response except Binding. Also it would be nice to see in the logs when the client is stopping.
Some of our recent testing is more explicit and clearer:
alias Jerboa.Test.Helper.XORMappedAddress, as: XORMAHelper
alias Jerboa.Test.Helper.Attribute, as: AHelper
test "IPv4 XORMappedAddress as a TLV" do
attr = XORMAHelper.struct(4)
bin = Attribute.encode %Format{}, attr
assert type(bin) === 0x0020
assert length_(bin) === AHelper.total(address: 32, other: 32)
end
Older testing did something like the following (repetitive between cases too):
test "IPv4 XORMappedAddress as a TLV" do
f = :ipv4
a = {0, 0, 0, 0}
p = 0
attr = %Attribute.XORMappedAddress{family: f, address: a, port: p}
bin = Attribute.encode %Format{}, attr
assert <<0x0020::16, 8::16, _::64>> = bin
end
Let's change this everywhere with separate assertions (and improve the helper modules) for readability.
Currently %Jerboa.Format{}
is a struct which carries information about decoded or not-yet-encoded STUN message. However its name does not represent its meaning.
@Dzol @michalwski any ideas?
In https://github.com/esl/jerboa/blob/master/lib/jerboa/format/header/type.ex#L41 we have:
def encode(:binding), do: <<0x001::12>>
...
def decode(<<0x001::12>>), do: {:ok, :binding}
This issue is about adding proper function clauses for TURN Allocate method. Refer to STUN RFC for format of STUN header and to TURN RFC for binary format of TURN methods.
Continues on from #18.
This includes sending Send indications with desired data and receiving Data indications sent from the server (probably in a synchronous manner for start).
Refer to #40
Currently Jerboa only does encoding + decoding (all this is under the format directory) but there are higher level concerns.
Only certain STUN classes are permissible on each STUN method (e.g. we can't have a binding indication). The Format
modules are wholly and exclusively responsible for encoding + decoding so this is not their concern.
We need to introduce a layer to handle this logic which is more akin to the kind of validation a parser does (as opposed to a scanner/lexer which is sort of what we have at the moment).
Parts common to server and client can make their way into Jerboa (though I expect this is going to be quite thin).
As @Arkham suggested, we should probably add an explanation of STUN protocol and its use cases to the README, for people not familiar with it. The same thing for TURN, once we implement it.
Refer to #40
Please refer to #36
It seems that to support long-term credentials, which we certainly want to do, we need to implement MESSAGE-INTEGRITY attribute.
It's one of two "hardcore" attributes, meaning that it needs to be calculated after the rest of a message is encoded, which at this point breaks a flow of our encoder/decoder.
This is something which needs to be discussed.
Introduce a simple client process, talking only over UDP, using only binding requests. I think for now we should not be bothered by specific recommendations of RFC.
Some of the TURN attributes which are not implemented yet must be validated by the server. Currently when Fennec encounters message with such attributes it will crash, because Jerboa raises on unknown RFC (as per RFC, unknown comprehension required attributes indicate that the message should be dropped).
For start, we need to implement three of them:
Introduce new Client API for sending data over existing channel and receiving it on one of the channels.
TURN RFC requires TURN client to send this attribute with Allocate request.
Refer to #40.
This mentioned in #12.
Refer to #40
This including creating and refreshing permissions via requests, and keeping permissions in Client's state.
Need to figure out how to decide whether message passed to decoder is STUN formatted or "channel data" formatted.
I've done an experiment with Protocols by using the to encoding/decoding the attributes. See protocol-based-attrs branch. I'm gonna look into it if it gives us any advantages.
Please refer to #36
This is being addressed by #67
In https://tools.ietf.org/html/rfc5389#page-10 there is:
def encode(p, a = %Attribute.XORMappedAddress{}) do
encode_(0x0020, Attribute.XORMappedAddress.encode(p, a))
end
def decode(params, 0x0020, v) do
Attribute.XORMappedAddress.decode params, v
end
This task is about adding one clause to each of these functions, and creating a module with functions responsible for encoding and decoding Lifetime attribute's value, similar to what XORMappedAddress
module does.
More info:
Currently Params.get_attr/2
returns only first occurence of attribute, and Params.put_attr/2
overrides attribute if such attribute already exists in the struct. We should add an API for retrieving multiple attributes of the same type, which makes sense only for XOR-PEER-ADDRESS
.
Refer to #40
Each function is documented, however overall documentation of working with Client module is not complete.
Some helpers reside in the helper directory.
Where there are common helper functions, e.g. repeated across test files, let's move them under this directory. They could potentially help to isolate and build property test generators too.
Right now our implementation of REQUESTED-TRANSPORT attribute only allows :udp
as a selected protocol. Every other value will raise during encoding, and raise or return an error when decoding such message.
It seemed convenient at the beginning - we aimed to be compliant only with original TURN RFC (for start) which allows only UDP as a requested relay transport.
However, this approach is not so good when working on a server side of things. There is a special error code which needs to be sent back by the server when it doesn't understand, provide or allow relay over requested transport protocol.
We need figure out how to decode this attribute when we don't know the protocol included, so that the server can use Jerboa to decode such message and respond appropriately.
This includes sending ChannelBind requests.
To be fair with anyone using our library, we should keep a list of methods supported by it. It could be a checklist, so that we know what is left to implement.
Refer to #40
master
.There are issues with server side processing of decoded messages, especially of current design of how verifying message integrity works. Currently there are three cases of decoding messages with MI:
note: secret can only be provided in options list
there are actually 4 cases, the last one is when message integrity is successfully verified
This all works well with client side code, because TURN client doesn't require the server to include message integrity - we just pass the secret every time, and if there is a message integrity, we try to verify it.
On the server side we would like to know if the message was verified after decoding it. Right now there is no way to know if decoded message was verified. My proposal it add :verified?
field to Jerboa.Params
struct.
In the first of mentioned situations, this field would be set to false, because there is nothing to verify - the request wasn't autenticated.
In the second example the decoding should succeed, but the field will be set to false again.
In the third case we could also let the decoding pass and set this flag to false.
When revising the documentation and on other occasions (recently) it would have been really helpful to see where we use the exception.
We moved them into their own file because we wanted shorter names.
To resolve both we can move them back into the same file as they're used but put them below the module they're used in. I.e. not nested in it.
Please refer to #36
ExDocs are for the client and encoding/decoding APIs.
Let's introduce a brief guide on developing internals.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.