summaryrefslogtreecommitdiff
path: root/channels/sip/config_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/sip/config_parser.c')
-rw-r--r--channels/sip/config_parser.c657
1 files changed, 657 insertions, 0 deletions
diff --git a/channels/sip/config_parser.c b/channels/sip/config_parser.c
new file mode 100644
index 000000000..c925d30cc
--- /dev/null
+++ b/channels/sip/config_parser.c
@@ -0,0 +1,657 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief sip config parsing functions and unit tests
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "include/sip.h"
+#include "include/config_parser.h"
+#include "include/sip_utils.h"
+
+/*! \brief Parse register=> line in sip.conf
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int sip_parse_register_line(struct sip_registry *reg, const char *value, int lineno)
+{
+ int portnum = 0;
+ enum sip_transport transport = SIP_TRANSPORT_UDP;
+ char buf[256] = "";
+ char *userpart = NULL, *hostpart = NULL;
+ /* register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] */
+ AST_DECLARE_APP_ARGS(pre1,
+ AST_APP_ARG(peer);
+ AST_APP_ARG(userpart);
+ );
+ AST_DECLARE_APP_ARGS(pre2,
+ AST_APP_ARG(transport);
+ AST_APP_ARG(blank);
+ AST_APP_ARG(userpart);
+ );
+ AST_DECLARE_APP_ARGS(user1,
+ AST_APP_ARG(userpart);
+ AST_APP_ARG(secret);
+ AST_APP_ARG(authuser);
+ );
+ AST_DECLARE_APP_ARGS(host1,
+ AST_APP_ARG(hostpart);
+ AST_APP_ARG(expiry);
+ );
+ AST_DECLARE_APP_ARGS(host2,
+ AST_APP_ARG(hostpart);
+ AST_APP_ARG(extension);
+ );
+ AST_DECLARE_APP_ARGS(host3,
+ AST_APP_ARG(host);
+ AST_APP_ARG(port);
+ );
+
+ if (!value) {
+ return -1;
+ }
+
+ if (!reg) {
+ return -1;
+ }
+ ast_copy_string(buf, value, sizeof(buf));
+
+ /*! register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry]
+ * becomes
+ * userpart => [peer?][transport://]user[@domain][:secret[:authuser]]
+ * hostpart => host[:port][/extension][~expiry]
+ */
+ if ((hostpart = strrchr(buf, '@'))) {
+ *hostpart++ = '\0';
+ userpart = buf;
+ }
+
+ if (ast_strlen_zero(userpart) || ast_strlen_zero(hostpart)) {
+ ast_log(LOG_WARNING, "Format for registration is [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] at line %d\n", lineno);
+ return -1;
+ }
+
+ /*!
+ * pre1.peer => peer
+ * pre1.userpart => [transport://]user[@domain][:secret[:authuser]]
+ * hostpart => host[:port][/extension][~expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(pre1, userpart, '?');
+ if (ast_strlen_zero(pre1.userpart)) {
+ pre1.userpart = pre1.peer;
+ pre1.peer = NULL;
+ }
+
+ /*!
+ * pre1.peer => peer
+ * pre2.transport = transport
+ * pre2.userpart => user[@domain][:secret[:authuser]]
+ * hostpart => host[:port][/extension][~expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(pre2, pre1.userpart, '/');
+ if (ast_strlen_zero(pre2.userpart)) {
+ pre2.userpart = pre2.transport;
+ pre2.transport = NULL;
+ } else {
+ pre2.transport[strlen(pre2.transport) - 1] = '\0'; /* Remove trailing : */
+ }
+
+ if (!ast_strlen_zero(pre2.blank)) {
+ ast_log(LOG_WARNING, "Format for registration is [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] at line %d\n", lineno);
+ return -1;
+ }
+
+ /*!
+ * pre1.peer => peer
+ * pre2.transport = transport
+ * user1.userpart => user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * hostpart => host[:port][/extension][~expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(user1, pre2.userpart, ':');
+
+ /*!
+ * pre1.peer => peer
+ * pre2.transport = transport
+ * user1.userpart => user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * host1.hostpart => host[:port][/extension]
+ * host1.expiry => [expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(host1, hostpart, '~');
+
+ /*!
+ * pre1.peer => peer
+ * pre2.transport = transport
+ * user1.userpart => user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * host2.hostpart => host[:port]
+ * host2.extension => [extension]
+ * host1.expiry => [expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(host2, host1.hostpart, '/');
+
+ /*!
+ * pre1.peer => peer
+ * pre2.transport = transport
+ * user1.userpart => user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * host3.host => host
+ * host3.port => port
+ * host2.extension => extension
+ * host1.expiry => expiry
+ */
+ AST_NONSTANDARD_RAW_ARGS(host3, host2.hostpart, ':');
+
+ if (host3.port) {
+ if (!(portnum = port_str2int(host3.port, 0))) {
+ ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", host3.port, lineno);
+ }
+ }
+
+ /* set transport type */
+ if (!pre2.transport) {
+ transport = SIP_TRANSPORT_UDP;
+ } else if (!strncasecmp(pre2.transport, "tcp", 3)) {
+ transport = SIP_TRANSPORT_TCP;
+ } else if (!strncasecmp(pre2.transport, "tls", 3)) {
+ transport = SIP_TRANSPORT_TLS;
+ } else if (!strncasecmp(pre2.transport, "udp", 3)) {
+ transport = SIP_TRANSPORT_UDP;
+ } else {
+ transport = SIP_TRANSPORT_UDP;
+ ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", pre2.transport, lineno);
+ }
+
+ /* if no portnum specified, set default for transport */
+ if (!portnum) {
+ if (transport == SIP_TRANSPORT_TLS) {
+ portnum = STANDARD_TLS_PORT;
+ } else {
+ portnum = STANDARD_SIP_PORT;
+ }
+ }
+
+ /* copy into sip_registry object */
+ ast_string_field_set(reg, callback, ast_strip_quoted(S_OR(host2.extension, "s"), "\"", "\""));
+ ast_string_field_set(reg, username, ast_strip_quoted(S_OR(user1.userpart, ""), "\"", "\""));
+ ast_string_field_set(reg, hostname, ast_strip_quoted(S_OR(host3.host, ""), "\"", "\""));
+ ast_string_field_set(reg, authuser, ast_strip_quoted(S_OR(user1.authuser, ""), "\"", "\""));
+ ast_string_field_set(reg, secret, ast_strip_quoted(S_OR(user1.secret, ""), "\"", "\""));
+ ast_string_field_set(reg, peername, ast_strip_quoted(S_OR(pre1.peer, ""), "\"", "\""));
+
+ reg->transport = transport;
+ reg->timeout = reg->expire = -1;
+ reg->portno = portnum;
+ reg->callid_valid = FALSE;
+ reg->ocseq = INITIAL_CSEQ;
+ if (!ast_strlen_zero(host1.expiry)) {
+ reg->refresh = reg->expiry = reg->configured_expiry = atoi(ast_strip_quoted(host1.expiry, "\"", "\""));
+ }
+
+ return 0;
+}
+
+AST_TEST_DEFINE(sip_parse_register_line_test)
+{
+ int res = AST_TEST_PASS;
+ struct sip_registry *reg;
+ const char *reg1 = "name@domain";
+ const char *reg2 = "name:pass@domain";
+ const char *reg3 = "name@namedomain:pass:authuser@domain";
+ const char *reg4 = "name@namedomain:pass:authuser@domain/extension";
+ const char *reg5 = "tcp://name@namedomain:pass:authuser@domain/extension";
+ const char *reg6 = "tls://name@namedomain:pass:authuser@domain/extension~111";
+ const char *reg7 = "peer?tcp://name@namedomain:pass:authuser@domain:1234/extension~111";
+ const char *reg8 = "peer?name@namedomain:pass:authuser@domain:1234/extension~111";
+ const char *reg9 = "peer?name:pass:authuser:1234/extension~111";
+ const char *reg10 = "@domin:1234";
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "sip_parse_register_line_test";
+ info->category = "channels/chan_sip/";
+ info->summary = "tests sip register line parsing";
+ info->description =
+ " Tests parsing of various register line configurations."
+ " Verifies output matches expected behavior.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ /* ---Test reg 1, simple config --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg1, 1) ||
+ strcmp(reg->callback, "s") ||
+ strcmp(reg->username, "name") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "") ||
+ strcmp(reg->secret, "") ||
+ strcmp(reg->peername, "") ||
+ reg->transport != SIP_TRANSPORT_UDP ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh ||
+ reg->expiry ||
+ reg->configured_expiry ||
+ reg->portno != STANDARD_SIP_PORT ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 1: simple config failed\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 2, add secret --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg2, 1) ||
+ strcmp(reg->callback, "s") ||
+ strcmp(reg->username, "name") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "") ||
+ strcmp(reg->secret, "pass") ||
+ strcmp(reg->peername, "") ||
+ reg->transport != SIP_TRANSPORT_UDP ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh ||
+ reg->expiry ||
+ reg->configured_expiry ||
+ reg->portno != STANDARD_SIP_PORT ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 2: add secret failed\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 3, add userdomain and authuser --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg3, 1) ||
+ strcmp(reg->callback, "s") ||
+ strcmp(reg->username, "name@namedomain") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "authuser") ||
+ strcmp(reg->secret, "pass") ||
+ strcmp(reg->peername, "") ||
+ reg->transport != SIP_TRANSPORT_UDP ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh ||
+ reg->expiry ||
+ reg->configured_expiry ||
+ reg->portno != STANDARD_SIP_PORT ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 3: add userdomain and authuser failed\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 4, add callback extension --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg4, 1) ||
+ strcmp(reg->callback, "extension") ||
+ strcmp(reg->username, "name@namedomain") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "authuser") ||
+ strcmp(reg->secret, "pass") ||
+ strcmp(reg->peername, "") ||
+ reg->transport != SIP_TRANSPORT_UDP ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh ||
+ reg->expiry ||
+ reg->configured_expiry ||
+ reg->portno != STANDARD_SIP_PORT ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 4: add callback extension failed\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 5, add transport --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg5, 1) ||
+ strcmp(reg->callback, "extension") ||
+ strcmp(reg->username, "name@namedomain") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "authuser") ||
+ strcmp(reg->secret, "pass") ||
+ strcmp(reg->peername, "") ||
+ reg->transport != SIP_TRANSPORT_TCP ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh ||
+ reg->expiry ||
+ reg->configured_expiry ||
+ reg->portno != STANDARD_SIP_PORT ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 5: add transport failed\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 6, change to tls transport, add expiry --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg6, 1) ||
+ strcmp(reg->callback, "extension") ||
+ strcmp(reg->username, "name@namedomain") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "authuser") ||
+ strcmp(reg->secret, "pass") ||
+ strcmp(reg->peername, "") ||
+ reg->transport != SIP_TRANSPORT_TLS ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh != 111 ||
+ reg->expiry != 111 ||
+ reg->configured_expiry != 111 ||
+ reg->portno != STANDARD_TLS_PORT ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 6: change to tls transport and add expiry failed\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 7, change transport to tcp, add custom port, and add peer --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg7, 1) ||
+ strcmp(reg->callback, "extension") ||
+ strcmp(reg->username, "name@namedomain") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "authuser") ||
+ strcmp(reg->secret, "pass") ||
+ strcmp(reg->peername, "peer") ||
+ reg->transport != SIP_TRANSPORT_TCP ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh != 111 ||
+ reg->expiry != 111 ||
+ reg->configured_expiry != 111 ||
+ reg->portno != 1234 ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 7, change transport to tcp, add custom port, and add peer failed.\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 8, remove transport --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (
+ sip_parse_register_line(reg, reg8, 1) ||
+ strcmp(reg->callback, "extension") ||
+ strcmp(reg->username, "name@namedomain") ||
+ strcmp(reg->hostname, "domain") ||
+ strcmp(reg->authuser, "authuser") ||
+ strcmp(reg->secret, "pass") ||
+ strcmp(reg->peername, "peer") ||
+ reg->transport != SIP_TRANSPORT_UDP ||
+ reg->timeout != -1 ||
+ reg->expire != -1 ||
+ reg->refresh != 111 ||
+ reg->expiry != 111 ||
+ reg->configured_expiry != 111 ||
+ reg->portno != 1234 ||
+ reg->callid_valid != FALSE ||
+ reg->ocseq != INITIAL_CSEQ) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 8, remove transport failed.\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 9, missing domain, expected to fail --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (!sip_parse_register_line(reg, reg9, 1)) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 9, missing domain, expected to fail but did not.\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 10, missing user, expected to fail --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (!sip_parse_register_line(reg, reg10, 1)) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 10, missing user expected to fail but did not\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+ /* ---Test reg 11, no registry object, expected to fail--- */
+ if (!sip_parse_register_line(NULL, reg1, 1)) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 11, no registery object, expected to fail but did not.\n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* ---Test reg 11, no registry line, expected to fail --- */
+ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
+ goto alloc_fail;
+ } else if (!sip_parse_register_line(reg, NULL, 1)) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 11, NULL register line expected to fail but did not.\n");
+ res = AST_TEST_FAIL;
+ }
+ ast_string_field_free_memory(reg);
+ ast_free(reg);
+
+
+ return res;
+
+alloc_fail:
+ ast_str_set(&args->ast_test_error_str, 0, "Out of memory. \n");
+ return res;
+}
+
+int sip_parse_host(char *line, int lineno, char **hostname, int *portnum, enum sip_transport *transport)
+{
+ char *port;
+
+ if (ast_strlen_zero(line)) {
+ return -1;
+ }
+ if ((*hostname = strstr(line, "://"))) {
+ *hostname += 3;
+
+ if (!strncasecmp(line, "tcp", 3))
+ *transport = SIP_TRANSPORT_TCP;
+ else if (!strncasecmp(line, "tls", 3))
+ *transport = SIP_TRANSPORT_TLS;
+ else if (!strncasecmp(line, "udp", 3))
+ *transport = SIP_TRANSPORT_UDP;
+ else
+ ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", line, lineno);
+ } else {
+ *hostname = line;
+ *transport = SIP_TRANSPORT_UDP;
+ }
+
+ if ((line = strrchr(*hostname, '@')))
+ line++;
+ else
+ line = *hostname;
+
+ if ((port = strrchr(line, ':'))) {
+ *port++ = '\0';
+
+ if (!sscanf(port, "%5u", portnum)) {
+ ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", port, lineno);
+ port = NULL;
+ }
+ }
+
+ if (!port) {
+ if (*transport & SIP_TRANSPORT_TLS) {
+ *portnum = STANDARD_TLS_PORT;
+ } else {
+ *portnum = STANDARD_SIP_PORT;
+ }
+ }
+
+ return 0;
+}
+
+AST_TEST_DEFINE(sip_parse_host_line_test)
+{
+ int res = AST_TEST_PASS;
+ char *host;
+ int port;
+ enum sip_transport transport;
+ char host1[] = "www.blah.com";
+ char host2[] = "tcp://www.blah.com";
+ char host3[] = "tls://10.10.10.10";
+ char host4[] = "tls://10.10.10.10:1234";
+ char host5[] = "10.10.10.10:1234";
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "sip_parse_host_line_test";
+ info->category = "channels/chan_sip/";
+ info->summary = "tests sip.conf host line parsing";
+ info->description =
+ " Tests parsing of various host line configurations."
+ " Verifies output matches expected behavior.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ /* test 1, simple host */
+ sip_parse_host(host1, 1, &host, &port, &transport);
+ if (port != STANDARD_SIP_PORT ||
+ ast_strlen_zero(host) || strcmp(host, "www.blah.com") ||
+ transport != SIP_TRANSPORT_UDP) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 1: simple host failed.\n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* test 2, add tcp transport */
+ sip_parse_host(host2, 1, &host, &port, &transport);
+ if (port != STANDARD_SIP_PORT ||
+ ast_strlen_zero(host) || strcmp(host, "www.blah.com") ||
+ transport != SIP_TRANSPORT_TCP) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 2: tcp host failed.\n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* test 3, add tls transport */
+ sip_parse_host(host3, 1, &host, &port, &transport);
+ if (port != STANDARD_TLS_PORT ||
+ ast_strlen_zero(host) || strcmp(host, "10.10.10.10") ||
+ transport != SIP_TRANSPORT_TLS) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 3: tls host failed. \n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* test 4, add custom port with tls */
+ sip_parse_host(host4, 1, &host, &port, &transport);
+ if (port != 1234 ||
+ ast_strlen_zero(host) || strcmp(host, "10.10.10.10") ||
+ transport != SIP_TRANSPORT_TLS) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 4: tls host with custom port failed.\n");
+ res = AST_TEST_FAIL;
+ }
+
+ /* test 5, simple host with custom port */
+ sip_parse_host(host5, 1, &host, &port, &transport);
+ if (port != 1234 ||
+ ast_strlen_zero(host) || strcmp(host, "10.10.10.10") ||
+ transport != SIP_TRANSPORT_UDP) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 5: simple host with custom port failed.\n");
+ res = AST_TEST_FAIL;
+ }
+ return res;
+
+ /* test 6, expected failure with NULL input */
+ if (sip_parse_host(NULL, 1, &host, &port, &transport)) {
+
+ ast_str_append(&args->ast_test_error_str, 0, "Test 6: expected error on NULL input did not occur.\n");
+ res = AST_TEST_FAIL;
+ }
+ return res;
+
+}
+
+/*! \brief SIP test registration */
+void sip_config_parser_register_tests(void)
+{
+ AST_TEST_REGISTER(sip_parse_register_line_test);
+ AST_TEST_REGISTER(sip_parse_host_line_test);
+}
+
+/*! \brief SIP test registration */
+void sip_config_parser_unregister_tests(void)
+{
+ AST_TEST_UNREGISTER(sip_parse_register_line_test);
+ AST_TEST_UNREGISTER(sip_parse_host_line_test);
+}
+