blob: ff74c715f19e621d81a36370d3da969863d99418 [file] [log] [blame]
James Kuszmaul4a42b182021-01-17 11:32:46 -08001#include "helper.h"
2#include "../ice_gatherer/gatherer.h"
3#include "../ice_server/server.h"
4#include <rawrtc/main.h>
5#include <rawrtcc/code.h>
6#include <rawrtcc/utils.h>
7#include <re.h>
8#include <rew.h>
9
10/*
11 * Destructor for an existing candidate helper.
12 */
13static void rawrtc_candidate_helper_destroy(void* arg) {
14 struct rawrtc_candidate_helper* const local_candidate = arg;
15
16 // Un-reference
17 list_flush(&local_candidate->stun_sessions);
18 mem_deref(local_candidate->udp_helper);
19 mem_deref(local_candidate->candidate);
20 mem_deref(local_candidate->gatherer);
21}
22
23/*
24 * Create a candidate helper.
25 */
26enum rawrtc_code rawrtc_candidate_helper_create(
27 struct rawrtc_candidate_helper** const candidate_helperp, // de-referenced
28 struct rawrtc_ice_gatherer* gatherer,
29 struct ice_lcand* const candidate,
30 udp_helper_recv_h* const receive_handler,
31 void* const arg) {
32 struct rawrtc_candidate_helper* candidate_helper;
33 enum rawrtc_code error;
34
35 // Check arguments
36 if (!candidate_helperp || !gatherer || !candidate || !receive_handler) {
37 return RAWRTC_CODE_INVALID_ARGUMENT;
38 }
39
40 // Create candidate helper
41 candidate_helper = mem_zalloc(sizeof(*candidate_helper), rawrtc_candidate_helper_destroy);
42 if (!candidate_helper) {
43 return RAWRTC_CODE_NO_MEMORY;
44 }
45
46 // Set fields
47 candidate_helper->gatherer = mem_ref(gatherer);
48 candidate_helper->candidate = mem_ref(candidate);
49 candidate_helper->srflx_pending_count = 0;
50 candidate_helper->relay_pending_count = 0;
51
52 // Set receive handler
53 error = rawrtc_candidate_helper_set_receive_handler(candidate_helper, receive_handler, arg);
54 if (error) {
55 goto out;
56 }
57
58out:
59 if (error) {
60 mem_deref(candidate_helper);
61 } else {
62 // Set pointer
63 *candidate_helperp = candidate_helper;
64 }
65 return error;
66}
67
68/*
69 * Set a candidate helper's receive handler.
70 */
71enum rawrtc_code rawrtc_candidate_helper_set_receive_handler(
72 struct rawrtc_candidate_helper* const candidate_helper,
73 udp_helper_recv_h* const receive_handler,
74 void* const arg) {
75 enum rawrtc_code error;
76 struct udp_helper* udp_helper;
77 struct udp_sock* udp_socket;
78
79 // Check arguments
80 if (!candidate_helper || !receive_handler) {
81 return RAWRTC_CODE_INVALID_ARGUMENT;
82 }
83
84 // Get local candidate's UDP socket
85 udp_socket = trice_lcand_sock(candidate_helper->gatherer->ice, candidate_helper->candidate);
86 if (!udp_socket) {
87 return RAWRTC_CODE_NO_SOCKET;
88 }
89
90 // Create UDP helper
91 error = rawrtc_error_to_code(udp_register_helper(
92 &udp_helper, udp_socket, RAWRTC_LAYER_DTLS_SRTP_STUN, NULL, receive_handler, arg));
93 if (error) {
94 return error;
95 }
96
97 // Unset current helper (if any) and set new helper
98 mem_deref(candidate_helper->udp_helper);
99 candidate_helper->udp_helper = udp_helper;
100
101 // TODO: What about TCP helpers?
102
103 // Done
104 return RAWRTC_CODE_SUCCESS;
105}
106
107/*
108 * Find a specific candidate helper by re candidate.
109 */
110enum rawrtc_code rawrtc_candidate_helper_find(
111 struct rawrtc_candidate_helper** const candidate_helperp,
112 struct list* const candidate_helpers,
113 struct ice_lcand* re_candidate) {
114 struct le* le;
115
116 // Check arguments
117 if (!candidate_helperp || !candidate_helpers || !re_candidate) {
118 return RAWRTC_CODE_INVALID_ARGUMENT;
119 }
120
121 // Lookup candidate helper
122 for (le = list_head(candidate_helpers); le != NULL; le = le->next) {
123 struct rawrtc_candidate_helper* const candidate_helper = le->data;
124 if (candidate_helper->candidate->us == re_candidate->us) {
125 // Found
126 *candidate_helperp = candidate_helper;
127 return RAWRTC_CODE_SUCCESS;
128 }
129 }
130
131 // Not found
132 return RAWRTC_CODE_NO_VALUE;
133}
134
135static void rawrtc_candidate_helper_stun_session_destroy(void* arg) {
136 struct rawrtc_candidate_helper_stun_session* const session = arg;
137
138 // Remove from list
139 list_unlink(&session->le);
140
141 // Un-reference
142 mem_deref(session->url);
143 mem_deref(session->stun_keepalive);
144 mem_deref(session->candidate_helper);
145}
146
147/*
148 * Create a STUN session.
149 */
150enum rawrtc_code rawrtc_candidate_helper_stun_session_create(
151 struct rawrtc_candidate_helper_stun_session** const sessionp, // de-referenced
152 struct rawrtc_ice_server_url* const url) {
153 struct rawrtc_candidate_helper_stun_session* session;
154
155 // Check arguments
156 if (!sessionp || !url) {
157 return RAWRTC_CODE_INVALID_ARGUMENT;
158 }
159
160 // Allocate
161 session = mem_zalloc(sizeof(*session), rawrtc_candidate_helper_stun_session_destroy);
162 if (!session) {
163 return RAWRTC_CODE_NO_MEMORY;
164 }
165
166 // Set fields/reference
167 session->url = mem_ref(url);
168 session->pending = true;
169
170 // Set pointer & done
171 *sessionp = session;
172 return RAWRTC_CODE_SUCCESS;
173}
174
175/*
176 * Add a STUN session to a candidate helper.
177 */
178enum rawrtc_code rawrtc_candidate_helper_stun_session_add(
179 struct rawrtc_candidate_helper_stun_session* const session,
180 struct rawrtc_candidate_helper* const candidate_helper,
181 struct stun_keepalive* const stun_keepalive) {
182 // Check arguments
183 if (!session || !candidate_helper || !stun_keepalive) {
184 return RAWRTC_CODE_INVALID_ARGUMENT;
185 }
186
187 // Set fields/reference
188 session->candidate_helper = mem_ref(candidate_helper);
189 session->stun_keepalive = mem_ref(stun_keepalive);
190
191 // Append to STUN sessions
192 list_append(&candidate_helper->stun_sessions, &session->le, session);
193
194 // Done
195 return RAWRTC_CODE_SUCCESS;
196}
197
198/*
199 * Remove STUN sessions list handler (for candidate helper lists).
200 */
201bool rawrtc_candidate_helper_remove_stun_sessions_handler(struct le* le, void* arg) {
202 struct rawrtc_candidate_helper* const candidate_helper = le->data;
203 (void) arg;
204
205 // Flush STUN sessions
206 list_flush(&candidate_helper->stun_sessions);
207
208 return false; // continue traversing
209}