2 * This file is part of the Nice GLib ICE library.
4 * (C) 2007 Nokia Corporation. All rights reserved.
5 * Contact: Rémi Denis-Courmont
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is the Nice GLib ICE library.
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
23 * Rémi Denis-Courmont, Nokia
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
40 #include <sys/types.h>
41 #include "stun/stunagent.h"
42 #include "stun/usages/ice.h"
55 #define MSG_DONTWAIT 0
56 #define MSG_NOSIGNAL 0
60 #include <sys/types.h>
61 #include <sys/socket.h>
62 #include <arpa/inet.h>
63 #include <netinet/in.h>
67 #undef NDEBUG /* ensure assertions are built-in */
75 struct sockaddr_storage storage;
76 struct sockaddr_in ip4;
78 uint8_t req_buf[STUN_MAX_MESSAGE_SIZE];
79 uint8_t resp_buf[STUN_MAX_MESSAGE_SIZE];
80 const uint64_t tie = 0x8000000000000000LL;
81 StunMessageReturn val;
82 StunUsageIceReturn val2;
85 static char username[] = "L:R";
86 static uint8_t ufrag[] = "L", pass[] = "secret";
87 size_t ufrag_len = strlen ((char*) ufrag);
88 size_t pass_len = strlen ((char*) pass);
94 StunDefaultValidaterData validater_data[] = {
95 {ufrag, ufrag_len, pass, pass_len},
96 {(uint8_t *) username, strlen (username), pass, pass_len},
98 StunValidationStatus valid;
100 stun_agent_init (&agent, STUN_ALL_KNOWN_ATTRIBUTES,
101 STUN_COMPATIBILITY_RFC5389,
102 STUN_AGENT_USAGE_USE_FINGERPRINT |
103 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS);
105 memset (&addr, 0, sizeof (addr));
106 addr.ip4.sin_family = AF_INET;
108 addr.ip4.sin_len = sizeof (addr);
110 addr.ip4.sin_port = htons (12345);
111 addr.ip4.sin_addr.s_addr = htonl (0x7f000001);
113 /* Incorrect message class */
114 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
115 assert (stun_agent_init_response (&agent, &req, req_buf, sizeof (req_buf), &req));
117 rlen = stun_agent_finish_message (&agent, &req, NULL, 0);
120 len = sizeof (resp_buf);
121 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
122 &resp, resp_buf, &len, &addr.storage,
123 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
124 assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_REQUEST);
127 /* Incorrect message method */
128 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), 0x666));
129 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username);
130 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
131 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
134 len = sizeof (resp_buf);
135 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
136 &resp, resp_buf, &len, &addr.storage,
137 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
138 assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_METHOD);
141 /* Unknown attribute */
142 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
143 val = stun_message_append_string (&req, 0x666, "The evil unknown attribute!");
144 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
145 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username);
146 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
147 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
150 valid = stun_agent_validate (&agent, &req, req_buf, rlen,
151 stun_agent_default_validater, validater_data);
153 assert (valid == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE);
155 /* Unauthenticated message */
156 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
157 rlen = stun_agent_finish_message (&agent, &req, NULL, 0);
160 valid = stun_agent_validate (&agent, &req, req_buf, rlen,
161 stun_agent_default_validater, validater_data);
163 assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST);
166 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
167 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
170 valid = stun_agent_validate (&agent, &req, req_buf, rlen,
171 stun_agent_default_validater, validater_data);
173 assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST);
174 assert (stun_usage_ice_conncheck_priority (&req) == 0);
175 assert (stun_usage_ice_conncheck_use_candidate (&req) == false);
178 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
179 val = stun_message_append32 (&req, STUN_ATTRIBUTE_PRIORITY, 0x12345678);
180 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
181 val = stun_message_append_flag (&req, STUN_ATTRIBUTE_USE_CANDIDATE);
182 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
183 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
185 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
186 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
189 len = sizeof (resp_buf);
190 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
191 &resp, resp_buf, &len, &addr.storage,
192 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
193 assert (val2 == STUN_USAGE_ICE_RETURN_SUCCESS);
195 assert (stun_agent_validate (&agent, &resp, resp_buf, len,
196 stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
197 assert (stun_message_get_class (&resp) == STUN_RESPONSE);
198 assert (stun_usage_ice_conncheck_priority (&req) == 0x12345678);
199 assert (stun_usage_ice_conncheck_use_candidate (&req) == true);
201 /* Invalid socket address */
202 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
203 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
205 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
206 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
209 addr.ip4.sin_family = AF_UNSPEC;
210 len = sizeof (resp_buf);
211 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
212 &resp, resp_buf, &len, &addr.storage,
213 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
214 assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_ADDRESS);
217 addr.ip4.sin_family = AF_INET;
219 /* Role conflict, controlling + ICE-CONTROLLING, switching controlled */
220 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
221 val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLING, tie + 1);
222 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
223 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
225 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
226 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
229 len = sizeof (resp_buf);
231 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
232 &resp, resp_buf, &len, &addr.storage,
233 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
234 assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
236 assert (control == false);
237 assert (stun_agent_validate (&agent, &resp, resp_buf, len,
238 stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
239 assert (stun_message_get_class (&resp) == STUN_RESPONSE);
241 /* Role conflict, controlled + ICE-CONTROLLED, switching controlling */
242 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
243 val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLED, tie - 1);
244 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
245 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
247 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
248 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
251 len = sizeof (resp_buf);
253 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
254 &resp, resp_buf, &len, &addr.storage,
255 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
256 assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
258 assert (control == true);
259 assert (stun_agent_validate (&agent, &resp, resp_buf, len,
260 stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
261 assert (stun_message_get_class (&resp) == STUN_RESPONSE);
263 /* Role conflict, controlling + ICE-CONTROLLING, staying controlling */
264 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
265 val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLING, tie - 1);
266 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
267 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
269 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
270 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
273 len = sizeof (resp_buf);
275 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
276 &resp, resp_buf, &len, &addr.storage,
277 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
278 assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
280 assert (control == true);
281 assert (stun_agent_validate (&agent, &resp, resp_buf, len,
282 stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
283 assert (stun_message_get_class (&resp) == STUN_ERROR);
284 stun_message_find_error (&resp, &code);
285 assert (code == STUN_ERROR_ROLE_CONFLICT);
287 /* Role conflict, controlled + ICE-CONTROLLED, staying controlling */
288 assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
289 val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLED, tie + 1);
290 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
291 val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
293 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
294 rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
297 len = sizeof (resp_buf);
299 val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
300 &resp, resp_buf, &len, &addr.storage,
301 sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
302 assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
304 assert (control == false);
305 assert (stun_agent_validate (&agent, &resp, resp_buf, len,
306 stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
307 assert (stun_message_get_class (&resp) == STUN_ERROR);
308 stun_message_find_error (&resp, &code);
309 assert (code == STUN_ERROR_ROLE_CONFLICT);