@@ -124,8 +124,13 @@ defmodule Rel.Listener do
124
124
Logger . info ( "Received new allocation request" )
125
125
{ c_ip , c_port , _ , _ , _ } = five_tuple
126
126
127
+ handle_error = fn reason , socket , c_ip , c_port , msg ->
128
+ { response , log_msg } = Utils . build_error ( reason , msg . transaction_id , msg . type . method )
129
+ Logger . warning ( log_msg )
130
+ :ok = :gen_udp . send ( socket , c_ip , c_port , response )
131
+ end
132
+
127
133
with { :ok , key } <- Auth . authenticate ( msg ) ,
128
- :ok <- is_not_retransmited? ( msg , key , [ ] ) ,
129
134
:ok <- refute_allocation ( five_tuple ) ,
130
135
:ok <- check_requested_transport ( msg ) ,
131
136
:ok <- check_dont_fragment ( msg ) ,
@@ -169,24 +174,39 @@ defmodule Rel.Listener do
169
174
{ :ok , alloc_pid } =
170
175
DynamicSupervisor . start_child (
171
176
Rel.AllocationSupervisor ,
172
- { Rel.AllocationHandler , [ five_tuple , alloc_socket , socket , username , lifetime ] }
177
+ { Rel.AllocationHandler ,
178
+ [
179
+ five_tuple: five_tuple ,
180
+ alloc_socket: alloc_socket ,
181
+ turn_socket: socket ,
182
+ username: username ,
183
+ time_to_expiry: lifetime ,
184
+ t_id: msg . transaction_id ,
185
+ response: response
186
+ ] }
173
187
)
174
188
175
189
:ok = :gen_udp . controlling_process ( alloc_socket , alloc_pid )
176
190
177
191
:ok = :gen_udp . send ( socket , c_ip , c_port , response )
178
192
else
193
+ { :error , :allocation_exists , % { t_id: origin_t_id , response: origin_response } }
194
+ when origin_t_id == msg . transaction_id ->
195
+ Logger . info ( "Allocation request retransmission" )
196
+ :ok = :gen_udp . send ( socket , c_ip , c_port , origin_response )
197
+
198
+ { :error , :allocation_exists , _alloc_origin_state } ->
199
+ handle_error . ( :allocation_exists , socket , c_ip , c_port , msg )
200
+
179
201
{ :error , reason } ->
180
- { response , log_msg } = Utils . build_error ( reason , msg . transaction_id , msg . type . method )
181
- Logger . warning ( log_msg )
182
- :ok = :gen_udp . send ( socket , c_ip , c_port , response )
202
+ handle_error . ( reason , socket , c_ip , c_port , msg )
183
203
end
184
204
end
185
205
186
206
defp handle_message ( socket , five_tuple , msg ) do
187
207
# TODO: are Registry entries removed fast enough?
188
208
case fetch_allocation ( five_tuple ) do
189
- { :ok , alloc } ->
209
+ { :ok , alloc , _alloc_origin_state } ->
190
210
AllocationHandler . process_message ( alloc , msg )
191
211
192
212
{ :error , :allocation_not_found = reason } ->
@@ -209,22 +229,17 @@ defmodule Rel.Listener do
209
229
end
210
230
end
211
231
212
- defp is_not_retransmited? ( _msg , _key , _allocation_requests ) do
213
- # TODO: handle retransmitions, RFC 5766 6.2
214
- :ok
215
- end
216
-
217
232
defp fetch_allocation ( five_tuple ) do
218
233
case Registry . lookup ( Registry.Allocations , five_tuple ) do
219
- [ { allocation , _value } ] -> { :ok , allocation }
234
+ [ { alloc , alloc_origin_state } ] -> { :ok , alloc , alloc_origin_state }
220
235
[ ] -> { :error , :allocation_not_found }
221
236
end
222
237
end
223
238
224
239
defp refute_allocation ( five_tuple ) do
225
240
case fetch_allocation ( five_tuple ) do
226
241
{ :error , :allocation_not_found } -> :ok
227
- { :ok , _alloc } -> { :error , :allocation_exists }
242
+ { :ok , _alloc , alloc_origin_state } -> { :error , :allocation_exists , alloc_origin_state }
228
243
end
229
244
end
230
245
@@ -295,6 +310,7 @@ defmodule Rel.Listener do
295
310
used_alloc_ports =
296
311
Registry.Allocations
297
312
|> Registry . select ( [ { { :_ , :_ , :"$3" } , [ ] , [ :"$3" ] } ] )
313
+ |> Enum . map ( fn alloc_origin_state -> Map . fetch! ( alloc_origin_state , :alloc_port ) end )
298
314
|> MapSet . new ( )
299
315
300
316
available_alloc_ports = MapSet . difference ( @ default_alloc_ports , used_alloc_ports )
0 commit comments