ICE over TCP/TLS
Ring will need to implement a group chat functionality. This needs to work on a fully distributed network, and without any central authority.
Moreover, we still need to implement p2p file transfer (see https://git.ring.cx/savoirfairelinux/ring-project/wikis/tutorials/File-transfer#future).
To be able to do that. A big step is to implement TCP Candidates with Interactive Connectivity Establishment (ICE) known as RFC 6544 (https://tools.ietf.org/html/rfc6544). This issue is here to be able to follow the work on this issue. The idea is to implement this directly in PJSIP
.
Also this will allow us to have SIP
over TCP
, and will allow us to ensure that any packet is correctly transferred (for example, if we want to use the DHT to init the conversation and then pass all messages through a direct connection when possible).
Retrieving candidates.
When agents perform address allocations to gather TCP-based
candidates, three types of candidates can be obtained: active
candidates, passive candidates, and simultaneous-open (S-O)
candidates. An active candidate is one for which the agent will
attempt to open an outbound connection but will not receive incoming
connection requests. A passive candidate is one for which the agent
will receive incoming connection attempts but not attempt a
connection. An S-O candidate is one for which the agent will attempt
to open a connection simultaneously with its peer.
Add option to get UDP or TCP candidates
Providers of real-time communications services may decide that it is
preferable to have no media at all rather than to have media over
TCP. To allow for choice, it is RECOMMENDED that it be possible to
configure agents to either obtain or not obtain TCP candidates for
real-time media.
Discover Host candidates
Status: DONE! See https://github.com/AmarOk1412/pjproject/commit/25eb13bef201cf79353191f57f5bd93628f016ce
When gathering candidates from a host interface, the agent typically
obtains active, passive, and S-O candidates.
Section 4.1:
First, agents SHOULD obtain host candidates as described in
Section 5.1. Then, each agent SHOULD "obtain" (allocate a
placeholder for) an active host candidate for each component of each
TCP-capable media stream on each interface that the host has. The
agent does not yet have to actually allocate a port for these
candidates, but they are used for the creation of the check lists.
Discover Server Reflexive Candidates
Connections to servers used for relayed and server
reflexive candidates are kept open during ICE processing.
Section 4.1:
The agent SHOULD then obtain server reflexive, NAT-assisted, and/or
UDP-tunneled candidates (see Section 5.2, Section 5.3, and
Section 5.4). The mechanisms for establishing these candidates and
the number of candidates to collect vary from technique to technique.
These considerations are discussed in the relevant sections.
Next, agents SHOULD obtain passive (and possibly S-O) relayed
candidates for each component as described in Section 5.5. Each
agent SHOULD also allocate a placeholder for an active relayed
candidate for each component of each TCP-capable media stream.
UPnP?
TBD
Prioritization
Section 4.2:
If a particular media stream can run over UDP or TCP, the UDP candidates might be preferred over the TCP connections
priority = (2^24)*(type preference) +
(2^8)*(local preference) +
(2^0)*(256 - component ID)
the new candidate types defined in
this document (see Section 5) are 105 for NAT-assisted candidates and
75 for UDP-tunneled candidates.
With TCP candidates, the local preference part of the recommended
priority formula is updated to also include the directionality
(active, passive, or simultaneous-open) of the TCP connection. The
RECOMMENDED local preference is then defined as:
local preference = (2^13) * direction-pref + other-pref
The direction-pref MUST be between 0 and 7 (both inclusive), with 7
being the most preferred. The other-pref MUST be between 0 and 8191
(both inclusive), with 8191 being the most preferred. It is
RECOMMENDED that the host, UDP-tunneled, and relayed TCP candidates
have the direction-pref assigned as follows: 6 for active, 4 for
passive, and 2 for S-O. For the NAT-assisted and server reflexive
candidates, the RECOMMENDED values are: 6 for S-O, 4 for active, and
2 for passive.
Default candidates
Status: DONE! See https://github.com/AmarOk1412/pjproject/commit/6d07ddab3e0a965e228e4332c0318a8d7455694c
The default candidate is chosen primarily based on the likelihood of
it working with a non-ICE peer. When media streams supporting mixed
modes (both TCP and UDP) are used with ICE, it is RECOMMENDED that,
for real-time streams (such as RTP), the default candidates be UDP-
based. However, the default SHOULD NOT be a simultaneous-open
candidate.
If a media stream is inherently TCP-based, it is RECOMMENDED for an
offering full agent to select an active candidate as the default
candidate and use [RFC4145] "setup" attribute value "active". This
increases the chances for a successful NAT traversal even without ICE
support if the agent is behind a NAT and the peer is not. For the
same reason, for a lite agent, it is RECOMMENDED to use a passive
candidate and "setup" attribute value "passive" in the offer.
Lite Implem
If an offerer meets the criteria for the lite mode as described in
Appendix A of [RFC5245] (i.e., it will always have a public, globally
unique IP address), it MAY use the lite mode of ICE for TCP
candidates. In the lite mode, for TCP candidates, only passive host
candidates are gathered, unless active candidates are needed as the
default candidates. Otherwise, the procedures described for lite
mode in [RFC5245] also apply to TCP candidates. If UDP and TCP
candidates are mixed in a media stream, the mode (lite or full)
applies to both UDP and TCP candidates.
Encoding/Decoding SDP
Status: DONE! See https://github.com/AmarOk1412/pjproject/commit/37bf2788cc9dc7e2cd2ef20e7136aec5f16fdd43
candidate-attribute = "candidate" ":" foundation SP component-id SP
"TCP" SP
priority SP
connection-address SP
port SP
cand-type
[SP rel-addr]
[SP rel-port]
SP tcp-type-ext
*(SP extension-att-name SP
extension-att-value)
tcp-type-ext = "tcptype" SP tcp-type
tcp-type = "active" / "passive" / "so"
Forming the checklist
Status: DONE! See: https://github.com/AmarOk1412/pjproject/commit/32e476cfa1c47af926697949939bfe34fb685008
6.2. Forming the Check Lists
As with UDP, check lists are formed only by full ICE implementations.
When forming candidate pairs, the following types of TCP candidates
can be paired with each other:
Local Remote
Candidate Candidate
---------------------------
tcp-so tcp-so
tcp-active tcp-passive
tcp-passive tcp-active
When the agent prunes the check list, it MUST also remove any pair
for which the local candidate is a passive TCP candidate. With
pruning, the NAT-assisted candidates are treated like server
reflexive candidates if the base is also used as a host candidate.
The remainder of check list processing works in the same way as the
UDP case.
Connectivity checks
Status: same as UDP
7. Connectivity Checks
The TCP connectivity checks, like with UDP, are generated only by
full implementations. The TCP candidate pairs are in the same check
list with the UDP candidate pairs, and they are scheduled for
connectivity checks, as described in Section 5.8 of [RFC5245], based
on the priority order.
TODO List:
For now, I forked the repo here: https://github.com/AmarOk1412/pjproject/tree/iceTCP
- ice_session gathering TCP candidates option and option to gather UDP candidates
- get host candidates
- get relayed candidates
- offer SDP
- checklist
- Simultaneous-open candidates?
- Use it with Ring!
14 Aug.
-
Listen on
0.0.0.0:xxxx
for the stun session -
SDP with correct port number
-
Separate incoming/outgoing for TCP
-
Connect when necessary
-
send first message on TCP