4
Original Author: Scott Godin
5
( s g o d i n AT s i p s p e c t r u m DOT c o m )
10
reTurn is a Stun/Turn server and client library implementation of the latest
11
Stun/Turn drafts: RFC5389, and draft-ietf-behave-turn-15
14
Current External Library Usage
15
------------------------------
16
- currently uses ASIO, BOOST and RUTIL
18
- Used for server sockets and transports
19
- Tuple information used in StunMessage uses asio::ip::udp::endpoint - easily changed
20
- StunMessage, TurnAllocation and RequestHandler use asio::ip:address to manipulate IPV6,
21
and IPV4 StunAddresses - easily changed
22
- StunTuple uses asio::ip::address - easily changed
24
- Using BOOST in no-lib mode is fine
25
- BOOST::bind is used in server transports
26
- BOOST::crc_optimal is used for fingerprint CRC calculations
27
- BOOST::shared_ptr, array, enable_shared_from_this is used in server transports
28
- RUTIL - Data class is used in StunMessage and StunAuth for strings and TurnData, SharedPtr is also used
31
Feature Implemented Tested Notes
32
-------------------------------------------------------------------
33
Configuration Framework partially yes Currently just uses a few command line parameters and hardcoded settings
34
RFC3489 support yes mostly
35
Multi-threaded Server no no Once Turn code is implemented consider asio threading model and provide locking
36
TLS Server Support yes yes
37
RFC5389 message parsing yes partly
38
IPV6 message parsing support yes no
39
Short Term Credentials yes yes Implementation currently only accepts one hardcoded username/password
40
Long Term Credentials mostly yes Implementation currently only accepts one hardcoded username/password
41
Finger Print Insertion and Validation yes yes Uses BOOST:crc_optimal
42
Checking for unknown attributes yes yes
44
Turn Allocation yes yes Only UDP Relay's are implemented
45
Requested Props (Even, Pair) yes yes
46
Turn Permissions yes yes
47
Turn UDP Relay yes yes
49
Asyncronous Client APIs yes yes
50
Channel Binding yes yes
51
Don't Fragment Attribute no no Server will reject requests asking for DF option
56
- reduce library use - remove BOOST and/or rutil requirement - remove ASIO for client??
57
- allow multiple interfaces to be used for relay
58
- per user allocation quota enforcement
59
- cleanup stun message class so that there are accessors for all data members
61
- Configuration Framework
62
- Multi-threaded support in Server
65
- Short Term passwords do not make any sense in reTurnServer (outside of RFC3489 backcompat) - they need to be supported on client APIs
69
- CreatePermission requests can contain multiple addresses - need to modify StunMessage in order to support this
70
- Clients need to install permissions before data can be sent - need to queue outbound data until CreateChannel response is received
71
- ChannelData messages must be padded to a multiple of 4 bytes, the padding is not to be reflected in the encoded length
72
- When client receives a Data Ind - it should ensure it is from an endpoint that it believes that it has installed a permission for, otherwise drop
73
- It is recommended that the client check if a permission exists towards the peer that just send a ChannelData message, if not - discard
74
- Could add checking that ChannelData messages always begin with bits 0b01, since bits 0b10 and 0b11 are reserved
75
- Need to give clients the ability to add Don't Fragment header to Allocate request
76
- If request with Don't Fragment fails with 420 code, then it can be retried without Don't Fragment (this will likely remain the responsibilty of the reTurn client application)
77
- It is recommended that the server impose limits on both the number of allocations active at one time for a given username and on the amount of bandwidth those allocations use. - 486 (Allocation Quota Exceeded)
78
- Port allocation algorithm should be better to ensure we won't run into collisions with other applications - port allocations should be random
79
- If the client receives a 400 response to a channel-bind request, then it is recommended that the allocation be deleted, and the client start again with a new allocation
83
-Username must contain UTF-8 sequence of bytes, and must have been processed by SASLprep
84
-Realm qdtext or quoted-pair - It must UTF-8 encoded and MUST be less than 128 characters (which can be as long as 763 bytes), and must be processed by SASLprep
85
-Nonce qdtext or quoted-pair - MUST be less than 128 characters (which can be as long as 763 bytes)
86
-Software must be a UTF-8 sequence of less than 128 characters (which can be as long as 763 byes)
87
-The Password used in the HMAC key must be SASLprep processed
88
-remove quotes and trailing nulls from username, realm. remove trailing nulls from password before forming MD5 hash for message integrity
89
-Errorcode Reason Phrase must be a UTF-8 sequence of less than 128 characters (which can be as long as 763 byes)
90
-need handling for 300 Try Alternate response - currently applications responsibility
91
-the following values should be configurable
92
- Initial RTO (default 500ms)
95
-actual RTO should be calculated
96
-UDP retransmissions should stop if a hard ICMP error is seen
97
-DNS SRV Discovery - currently only does host record lookup (using ASIO) - _stun._udp, _stun._tcp, _stuns._tcp, _turn._udp, _turn._tcp, _turns._tcp
101
- rework synchronous sockets to use Asynchrous sockets to unify implementation better
103
- add option to require message integrity? - depends on usage - ICE
104
- add ability to install a permission or binding without sending data
108
- retries should be paced at 500ms, 1000ms, 2000ms, etc. - after 442, 443, or 444 response - currently applications responsibility
109
- If a client receives a 437 allocation mismatch response to an allocate, then it should retry using a different client transport address - it should do this 3 times (this will likely remain the responsibilty of the reTurn client application)
110
- To prevent race conditions a client MUST wait 5 mins after the channel binding expires before attempting to bind the channel number to a different transport address or the transport address to a different channel number (within the same allocation?).
115
Current Asynchronous Implementation:
116
- Application must provide an asio::io_service object and is responsible for threading it out and calling run
117
- Async Turn sockets must be held in a shared pointer, in order to ensure safety of asio callbacks - this could be abstracted better
118
- When Async sockets are created a callback handler class is passed in to receive callback notifications when
119
operations are complete
121
API Set - Wrapping in a Turn(Async)Socket - Turn(Async)UdpSocket, Turn(Async)TcpSocket, Turn(Async)TlsSocket
122
- bound to local socket
123
* setUsernameAndPassword()
124
* requestSharedSecret() - username and password are returned
125
* createAllocation(lifetime,
129
requestedTransportType)
130
* refreshAllocation(lifetime)
131
* destroyAllocation()
132
* getRelayTuple() - (SYNC API ONLY) used to retrieve info about the allocation
133
* getReflexiveTuple() - (SYNC API ONLY) used to retrieve info about the allocation
134
* getLifetime() - (SYNC API ONLY) used to retrieve info about the allocation
135
* getBandwidth() - (SYNC API ONLY) used to retrieve info about the allocation
136
* setActiveDestination(destinationIP, destinationPort)
137
* clearActiveDestination()
139
* send(bufferToSend, bufferSize);
140
* sendTo(destinationIP, destinationPort, bufferToSend, bufferSize)
141
* receive(bufferToReceiveIn, bufferSize[in/out], senderIPAddress, senderPort)
142
- last 2 args are return args - if receive is non-blocking then this data is returned in callback instead
143
* receiveFrom(bufferToReceiveIn, bufferSize[in/out], senderIPAddress, senderPort)
144
- in this case last 2 args are input and specify endpoint we want to receive from
146
NOTE: could also add a binding discovery API for attempting to detect NAT type using RFC3489 methods
148
Asynchronous Callbacks:
150
onConnectSuccess(unsigned int socketDesc,
151
const asio::ip::address& address,
152
unsigned short port) = 0;
153
onConnectFailure(unsigned int socketDesc, const asio::error_code& e) = 0;
155
onSharedSecretSuccess(unsigned int socketDesc,
156
const char* username,
157
unsigned int usernameSize,
158
const char* password,
159
unsigned int passwordSize) = 0;
160
onSharedSecretFailure(unsigned int socketDesc, const asio::error_code& e) = 0;
162
onBindSuccess(unsigned int socketDesc, const StunTuple& reflexiveTuple) = 0;
163
onBindFailure(unsigned int socketDesc, const asio::error_code& e) = 0;
165
onAllocationSuccess(unsigned int socketDesc,
166
const StunTuple& reflexiveTuple,
167
const StunTuple& relayTuple,
168
unsigned int lifetime,
169
unsigned int bandwidth,
170
UInt64& reservationToken) = 0;
171
onAllocationFailure(unsigned int socketDesc, const asio::error_code& e) = 0;
173
onRefreshSuccess(unsigned int socketDesc, unsigned int lifetime) = 0;
174
onRefreshFailure(unsigned int socketDesc, const asio::error_code& e) = 0;
176
onSetActiveDestinationSuccess(unsigned int socketDesc) = 0;
177
onSetActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e) = 0;
178
onClearActiveDestinationSuccess(unsigned int socketDesc) = 0;
179
onClearActiveDestinationFailure(unsigned int socketDesc, const asio::error_code &e) = 0;
181
onReceiveSuccess(unsigned int socketDesc,
182
const asio::ip::address& address,
185
unsigned int size) = 0;
186
onReceiveFailure(unsigned int socketDesc, const asio::error_code& e) = 0;
188
onSendSuccess(unsigned int socketDesc) = 0;
189
onSendFailure(unsigned int socketDesc, const asio::error_code& e) = 0;
196
/* ====================================================================
198
Copyright (c) 2007-2008, Plantronics, Inc.
201
Redistribution and use in source and binary forms, with or without
202
modification, are permitted provided that the following conditions are
205
1. Redistributions of source code must retain the above copyright
206
notice, this list of conditions and the following disclaimer.
208
2. Redistributions in binary form must reproduce the above copyright
209
notice, this list of conditions and the following disclaimer in the
210
documentation and/or other materials provided with the distribution.
212
3. Neither the name of Plantronics nor the names of its contributors
213
may be used to endorse or promote products derived from this
214
software without specific prior written permission.
216
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
217
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
218
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
219
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
220
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
223
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
224
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
226
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
228
==================================================================== */