libnice/stun/tests/test-conncheck.c
Nirbheek Chauhan e4614618ba Fix build with MSVC
Tested inside Cerbero with VS 2017
2018-12-14 14:47:01 -05:00

312 lines
12 KiB
C

/*
* This file is part of the Nice GLib ICE library.
*
* (C) 2007 Nokia Corporation. All rights reserved.
* Contact: Rémi Denis-Courmont
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Nice GLib ICE library.
*
* The Initial Developers of the Original Code are Collabora Ltd and Nokia
* Corporation. All Rights Reserved.
*
* Contributors:
* Rémi Denis-Courmont, Nokia
*
* Alternatively, the contents of this file may be used under the terms of the
* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
* case the provisions of LGPL are applicable instead of those above. If you
* wish to allow use of your version of this file only under the terms of the
* LGPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replace
* them with the notice and other provisions required by the LGPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the LGPL.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include "stun/stunagent.h"
#include "stun/usages/ice.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#define MSG_DONTWAIT 0
#define MSG_NOSIGNAL 0
#define alarm(...)
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#undef NDEBUG /* ensure assertions are built-in */
#include <assert.h>
int main (void)
{
union {
struct sockaddr sa;
struct sockaddr_storage storage;
struct sockaddr_in ip4;
} addr;
uint8_t req_buf[STUN_MAX_MESSAGE_SIZE];
uint8_t resp_buf[STUN_MAX_MESSAGE_SIZE];
const uint64_t tie = 0x8000000000000000LL;
StunMessageReturn val;
StunUsageIceReturn val2;
size_t len;
size_t rlen;
static char username[] = "L:R";
static uint8_t ufrag[] = "L", pass[] = "secret";
size_t ufrag_len = strlen ((char*) ufrag);
size_t pass_len = strlen ((char*) pass);
int code;
bool control = false;
StunAgent agent;
StunMessage req;
StunMessage resp;
StunDefaultValidaterData validater_data[] = {
{ufrag, ufrag_len, pass, pass_len},
{(uint8_t *) username, strlen (username), pass, pass_len},
{NULL, 0, NULL, 0}};
StunValidationStatus valid;
stun_agent_init (&agent, STUN_ALL_KNOWN_ATTRIBUTES,
STUN_COMPATIBILITY_RFC5389,
STUN_AGENT_USAGE_USE_FINGERPRINT |
STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS);
memset (&addr, 0, sizeof (addr));
addr.ip4.sin_family = AF_INET;
#ifdef HAVE_SA_LEN
addr.ip4.sin_len = sizeof (addr);
#endif
addr.ip4.sin_port = htons (12345);
addr.ip4.sin_addr.s_addr = htonl (0x7f000001);
/* Incorrect message class */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
assert (stun_agent_init_response (&agent, &req, req_buf, sizeof (req_buf), &req));
rlen = stun_agent_finish_message (&agent, &req, NULL, 0);
assert (rlen > 0);
len = sizeof (resp_buf);
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_REQUEST);
assert (len == 0);
/* Incorrect message method */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), 0x666));
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
len = sizeof (resp_buf);
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_METHOD);
assert (len > 0);
/* Unknown attribute */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
val = stun_message_append_string (&req, 0x666, "The evil unknown attribute!");
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
valid = stun_agent_validate (&agent, &req, req_buf, rlen,
stun_agent_default_validater, validater_data);
assert (valid == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE);
/* Unauthenticated message */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
rlen = stun_agent_finish_message (&agent, &req, NULL, 0);
assert (rlen > 0);
valid = stun_agent_validate (&agent, &req, req_buf, rlen,
stun_agent_default_validater, validater_data);
assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST);
/* No username */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
valid = stun_agent_validate (&agent, &req, req_buf, rlen,
stun_agent_default_validater, validater_data);
assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST);
assert (stun_usage_ice_conncheck_priority (&req) == 0);
assert (stun_usage_ice_conncheck_use_candidate (&req) == false);
/* Good message */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
val = stun_message_append32 (&req, STUN_ATTRIBUTE_PRIORITY, 0x12345678);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
val = stun_message_append_flag (&req, STUN_ATTRIBUTE_USE_CANDIDATE);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
(char*) ufrag);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
len = sizeof (resp_buf);
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_SUCCESS);
assert (len > 0);
assert (stun_agent_validate (&agent, &resp, resp_buf, len,
stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
assert (stun_message_get_class (&resp) == STUN_RESPONSE);
assert (stun_usage_ice_conncheck_priority (&req) == 0x12345678);
assert (stun_usage_ice_conncheck_use_candidate (&req) == true);
/* Invalid socket address */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
(char *) ufrag);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
addr.ip4.sin_family = AF_UNSPEC;
len = sizeof (resp_buf);
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_ADDRESS);
assert (len == 0);
addr.ip4.sin_family = AF_INET;
/* Role conflict, controlling + ICE-CONTROLLING, switching controlled */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLING, tie + 1);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
(char *) ufrag);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
len = sizeof (resp_buf);
control = true;
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
assert (len > 0);
assert (control == false);
assert (stun_agent_validate (&agent, &resp, resp_buf, len,
stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
assert (stun_message_get_class (&resp) == STUN_RESPONSE);
/* Role conflict, controlled + ICE-CONTROLLED, switching controlling */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLED, tie - 1);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
(char *) ufrag);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
len = sizeof (resp_buf);
control = false;
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
assert (len > 0);
assert (control == true);
assert (stun_agent_validate (&agent, &resp, resp_buf, len,
stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
assert (stun_message_get_class (&resp) == STUN_RESPONSE);
/* Role conflict, controlling + ICE-CONTROLLING, staying controlling */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLING, tie - 1);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
(char *) ufrag);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
len = sizeof (resp_buf);
control = true;
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
assert (len > 0);
assert (control == true);
assert (stun_agent_validate (&agent, &resp, resp_buf, len,
stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
assert (stun_message_get_class (&resp) == STUN_ERROR);
stun_message_find_error (&resp, &code);
assert (code == STUN_ERROR_ROLE_CONFLICT);
/* Role conflict, controlled + ICE-CONTROLLED, staying controlling */
assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING));
val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLED, tie + 1);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME,
(char *) ufrag);
assert (val == STUN_MESSAGE_RETURN_SUCCESS);
rlen = stun_agent_finish_message (&agent, &req, pass, pass_len);
assert (rlen > 0);
len = sizeof (resp_buf);
control = false;
val2 = stun_usage_ice_conncheck_create_reply (&agent, &req,
&resp, resp_buf, &len, &addr.storage,
sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245);
assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT);
assert (len > 0);
assert (control == false);
assert (stun_agent_validate (&agent, &resp, resp_buf, len,
stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS);
assert (stun_message_get_class (&resp) == STUN_ERROR);
stun_message_find_error (&resp, &code);
assert (code == STUN_ERROR_ROLE_CONFLICT);
return 0;
}