Mon Mar 19 11:30:46 2012

Asterisk developer's documentation


config_parser.c File Reference

sip config parsing functions and unit tests More...

#include "asterisk.h"
#include "include/sip.h"
#include "include/config_parser.h"
#include "include/sip_utils.h"

Go to the source code of this file.

Functions

 AST_TEST_DEFINE (sip_parse_host_line_test)
 AST_TEST_DEFINE (sip_parse_register_line_test)
void sip_config_parser_register_tests (void)
 SIP test registration.
void sip_config_parser_unregister_tests (void)
 SIP test registration.
int sip_parse_host (char *line, int lineno, char **hostname, int *portnum, enum sip_transport *transport)
int sip_parse_register_line (struct sip_registry *reg, int default_expiry, const char *value, int lineno)
 Parse register=> line in sip.conf.


Detailed Description

sip config parsing functions and unit tests

Definition in file config_parser.c.


Function Documentation

AST_TEST_DEFINE ( sip_parse_host_line_test   ) 

Definition at line 688 of file config_parser.c.

References ast_strlen_zero(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_parse_host(), TEST_EXECUTE, and TEST_INIT.

00689 {
00690    int res = AST_TEST_PASS;
00691    char *host;
00692    int port;
00693    enum sip_transport transport;
00694    char host1[] = "www.blah.com";
00695    char host2[] = "tcp://www.blah.com";
00696    char host3[] = "tls://10.10.10.10";
00697    char host4[] = "tls://10.10.10.10:1234";
00698    char host5[] = "10.10.10.10:1234";
00699 
00700    switch (cmd) {
00701    case TEST_INIT:
00702       info->name = "sip_parse_host_line_test";
00703       info->category = "/channels/chan_sip/";
00704       info->summary = "tests sip.conf host line parsing";
00705       info->description =
00706                      "Tests parsing of various host line configurations. "
00707                      "Verifies output matches expected behavior.";
00708       return AST_TEST_NOT_RUN;
00709    case TEST_EXECUTE:
00710       break;
00711    }
00712 
00713    /* test 1, simple host */
00714    sip_parse_host(host1, 1, &host, &port, &transport);
00715    if (port != STANDARD_SIP_PORT ||
00716          ast_strlen_zero(host) || strcmp(host, "www.blah.com") ||
00717          transport != SIP_TRANSPORT_UDP) {
00718       ast_test_status_update(test, "Test 1: simple host failed.\n");
00719       res = AST_TEST_FAIL;
00720    }
00721 
00722    /* test 2, add tcp transport */
00723    sip_parse_host(host2, 1, &host, &port, &transport);
00724    if (port != STANDARD_SIP_PORT ||
00725          ast_strlen_zero(host) || strcmp(host, "www.blah.com") ||
00726          transport != SIP_TRANSPORT_TCP) {
00727       ast_test_status_update(test, "Test 2: tcp host failed.\n");
00728       res = AST_TEST_FAIL;
00729    }
00730 
00731    /* test 3, add tls transport */
00732    sip_parse_host(host3, 1, &host, &port, &transport);
00733    if (port != STANDARD_TLS_PORT ||
00734          ast_strlen_zero(host) || strcmp(host, "10.10.10.10") ||
00735          transport != SIP_TRANSPORT_TLS) {
00736       ast_test_status_update(test, "Test 3: tls host failed. \n");
00737       res = AST_TEST_FAIL;
00738    }
00739 
00740    /* test 4, add custom port with tls */
00741    sip_parse_host(host4, 1, &host, &port, &transport);
00742    if (port != 1234 || ast_strlen_zero(host) ||
00743          strcmp(host, "10.10.10.10") ||
00744          transport != SIP_TRANSPORT_TLS) {
00745       ast_test_status_update(test, "Test 4: tls host with custom port failed.\n");
00746       res = AST_TEST_FAIL;
00747    }
00748 
00749    /* test 5, simple host with custom port */
00750    sip_parse_host(host5, 1, &host, &port, &transport);
00751    if (port != 1234 || ast_strlen_zero(host) ||
00752          strcmp(host, "10.10.10.10") ||
00753          transport != SIP_TRANSPORT_UDP) {
00754       ast_test_status_update(test, "Test 5: simple host with custom port failed.\n");
00755       res = AST_TEST_FAIL;
00756    }
00757 
00758    /* test 6, expected failure with NULL input */
00759    if (!sip_parse_host(NULL, 1, &host, &port, &transport)) {
00760       ast_test_status_update(test, "Test 6: expected error on NULL input did not occur.\n");
00761       res = AST_TEST_FAIL;
00762    }
00763 
00764    return res;
00765 
00766 }

AST_TEST_DEFINE ( sip_parse_register_line_test   ) 

Definition at line 270 of file config_parser.c.

References ast_calloc_with_stringfields, ast_free, ast_string_field_free_memory, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, default_expiry, FALSE, sip_parse_register_line(), TEST_EXECUTE, and TEST_INIT.

00271 {
00272    int res = AST_TEST_PASS;
00273    struct sip_registry *reg;
00274    int default_expiry = 120;
00275    const char *reg1 = "name@domain";
00276    const char *reg2 = "name:pass@domain";
00277    const char *reg3 = "name@namedomain:pass:authuser@domain";
00278    const char *reg4 = "name@namedomain:pass:authuser@domain/extension";
00279    const char *reg5 = "tcp://name@namedomain:pass:authuser@domain/extension";
00280    const char *reg6 = "tls://name@namedomain:pass:authuser@domain/extension~111";
00281    const char *reg7 = "peer?tcp://name@namedomain:pass:authuser@domain:1234/extension~111";
00282    const char *reg8 = "peer?name@namedomain:pass:authuser@domain:1234/extension~111";
00283    const char *reg9 = "peer?name:pass:authuser:1234/extension~111";
00284    const char *reg10 = "@domin:1234";
00285    const char *reg12 = "name@namedomain:4321:pass:authuser@domain";
00286    const char *reg13 = "name@namedomain:4321::@domain";
00287 
00288    switch (cmd) {
00289    case TEST_INIT:
00290       info->name = "sip_parse_register_line_test";
00291       info->category = "/channels/chan_sip/";
00292       info->summary = "tests sip register line parsing";
00293       info->description =
00294                      "Tests parsing of various register line configurations. "
00295                      "Verifies output matches expected behavior.";
00296       return AST_TEST_NOT_RUN;
00297    case TEST_EXECUTE:
00298       break;
00299    }
00300 
00301    /* ---Test reg 1, simple config --- */
00302    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00303       goto alloc_fail;
00304    } else if (
00305        sip_parse_register_line(reg, default_expiry, reg1, 1) ||
00306       strcmp(reg->callback, "s")           ||
00307       strcmp(reg->username, "name")       ||
00308       strcmp(reg->regdomain, "")          ||
00309       strcmp(reg->hostname, "domain")     ||
00310       strcmp(reg->authuser, "")           ||
00311       strcmp(reg->secret, "")             ||
00312       strcmp(reg->peername, "")           ||
00313       reg->transport != SIP_TRANSPORT_UDP ||
00314       reg->timeout != -1                  ||
00315       reg->expire != -1                   ||
00316       reg->refresh != default_expiry ||
00317       reg->expiry != default_expiry ||
00318       reg->configured_expiry != default_expiry ||
00319       reg->portno != STANDARD_SIP_PORT    ||
00320       (reg->regdomainport)                ||
00321       reg->callid_valid != FALSE          ||
00322       reg->ocseq != INITIAL_CSEQ) {
00323 
00324       ast_test_status_update(test, "Test 1: simple config failed\n");
00325       res = AST_TEST_FAIL;
00326    }
00327    ast_string_field_free_memory(reg);
00328    ast_free(reg);
00329 
00330    /* ---Test reg 2, add secret --- */
00331    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00332       goto alloc_fail;
00333    } else if (
00334        sip_parse_register_line(reg, default_expiry, reg2, 1) ||
00335       strcmp(reg->callback, "s")           ||
00336       strcmp(reg->username, "name")       ||
00337       strcmp(reg->regdomain, "")          ||
00338       strcmp(reg->hostname, "domain")     ||
00339       strcmp(reg->authuser, "")           ||
00340       strcmp(reg->secret, "pass")         ||
00341       strcmp(reg->peername, "")           ||
00342       reg->transport != SIP_TRANSPORT_UDP ||
00343       reg->timeout != -1                  ||
00344       reg->expire != -1                   ||
00345       reg->refresh != default_expiry ||
00346       reg->expiry != default_expiry ||
00347       reg->configured_expiry != default_expiry ||
00348       reg->portno != STANDARD_SIP_PORT    ||
00349       (reg->regdomainport)                ||
00350       reg->callid_valid != FALSE          ||
00351       reg->ocseq != INITIAL_CSEQ) {
00352 
00353       ast_test_status_update(test,  "Test 2: add secret failed\n");
00354       res = AST_TEST_FAIL;
00355    }
00356    ast_string_field_free_memory(reg);
00357    ast_free(reg);
00358 
00359    /* ---Test reg 3, add userdomain and authuser --- */
00360    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00361       goto alloc_fail;
00362    } else if (
00363        sip_parse_register_line(reg, default_expiry, reg3, 1) ||
00364       strcmp(reg->callback, "s")           ||
00365       strcmp(reg->username, "name") ||
00366       strcmp(reg->regdomain, "namedomain") ||
00367       strcmp(reg->hostname, "domain")     ||
00368       strcmp(reg->authuser, "authuser")           ||
00369       strcmp(reg->secret, "pass")         ||
00370       strcmp(reg->peername, "")           ||
00371       reg->transport != SIP_TRANSPORT_UDP ||
00372       reg->timeout != -1                  ||
00373       reg->expire != -1                   ||
00374       reg->refresh != default_expiry ||
00375       reg->expiry != default_expiry ||
00376       reg->configured_expiry != default_expiry ||
00377       reg->portno != STANDARD_SIP_PORT    ||
00378       (reg->regdomainport)                ||
00379       reg->callid_valid != FALSE          ||
00380       reg->ocseq != INITIAL_CSEQ) {
00381 
00382       ast_test_status_update(test, "Test 3: add userdomain and authuser failed\n");
00383       res = AST_TEST_FAIL;
00384    }
00385    ast_string_field_free_memory(reg);
00386    ast_free(reg);
00387 
00388    /* ---Test reg 4, add callback extension --- */
00389    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00390       goto alloc_fail;
00391    } else if (
00392        sip_parse_register_line(reg, default_expiry, reg4, 1) ||
00393       strcmp(reg->callback, "extension")           ||
00394       strcmp(reg->username, "name") ||
00395       strcmp(reg->regdomain, "namedomain") ||
00396       strcmp(reg->hostname, "domain")     ||
00397       strcmp(reg->authuser, "authuser")           ||
00398       strcmp(reg->secret, "pass")         ||
00399       strcmp(reg->peername, "")           ||
00400       reg->transport != SIP_TRANSPORT_UDP ||
00401       reg->timeout != -1                  ||
00402       reg->expire != -1                   ||
00403       reg->refresh != default_expiry ||
00404       reg->expiry != default_expiry ||
00405       reg->configured_expiry != default_expiry ||
00406       reg->portno != STANDARD_SIP_PORT    ||
00407       (reg->regdomainport)                ||
00408       reg->callid_valid != FALSE          ||
00409       reg->ocseq != INITIAL_CSEQ) {
00410 
00411       ast_test_status_update(test, "Test 4: add callback extension failed\n");
00412       res = AST_TEST_FAIL;
00413    }
00414    ast_string_field_free_memory(reg);
00415    ast_free(reg);
00416 
00417    /* ---Test reg 5, add transport --- */
00418    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00419       goto alloc_fail;
00420    } else if (
00421        sip_parse_register_line(reg, default_expiry, reg5, 1) ||
00422       strcmp(reg->callback, "extension")           ||
00423       strcmp(reg->username, "name") ||
00424       strcmp(reg->regdomain, "namedomain") ||
00425       strcmp(reg->hostname, "domain")     ||
00426       strcmp(reg->authuser, "authuser")           ||
00427       strcmp(reg->secret, "pass")         ||
00428       strcmp(reg->peername, "")           ||
00429       reg->transport != SIP_TRANSPORT_TCP ||
00430       reg->timeout != -1                  ||
00431       reg->expire != -1                   ||
00432       reg->refresh != default_expiry ||
00433       reg->expiry != default_expiry ||
00434       reg->configured_expiry != default_expiry ||
00435       reg->portno != STANDARD_SIP_PORT    ||
00436       (reg->regdomainport)                ||
00437       reg->callid_valid != FALSE          ||
00438       reg->ocseq != INITIAL_CSEQ) {
00439 
00440       ast_test_status_update(test, "Test 5: add transport failed\n");
00441       res = AST_TEST_FAIL;
00442    }
00443    ast_string_field_free_memory(reg);
00444    ast_free(reg);
00445 
00446    /* ---Test reg 6, change to tls transport, add expiry  --- */
00447    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00448       goto alloc_fail;
00449    } else if (
00450        sip_parse_register_line(reg, default_expiry, reg6, 1) ||
00451       strcmp(reg->callback, "extension")           ||
00452       strcmp(reg->username, "name") ||
00453       strcmp(reg->regdomain, "namedomain") ||
00454       strcmp(reg->hostname, "domain")     ||
00455       strcmp(reg->authuser, "authuser")           ||
00456       strcmp(reg->secret, "pass")         ||
00457       strcmp(reg->peername, "")           ||
00458       reg->transport != SIP_TRANSPORT_TLS ||
00459       reg->timeout != -1                  ||
00460       reg->expire != -1                   ||
00461       reg->refresh != 111 ||
00462       reg->expiry != 111 ||
00463       reg->configured_expiry != 111 ||
00464       reg->portno != STANDARD_TLS_PORT    ||
00465       (reg->regdomainport)                ||
00466       reg->callid_valid != FALSE          ||
00467       reg->ocseq != INITIAL_CSEQ) {
00468 
00469       ast_test_status_update(test, "Test 6: change to tls transport and add expiry failed\n");
00470       res = AST_TEST_FAIL;
00471    }
00472    ast_string_field_free_memory(reg);
00473    ast_free(reg);
00474 
00475    /* ---Test reg 7, change transport to tcp, add custom port, and add peer --- */
00476    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00477       goto alloc_fail;
00478    } else if (
00479        sip_parse_register_line(reg, default_expiry, reg7, 1) ||
00480       strcmp(reg->callback, "extension")           ||
00481       strcmp(reg->username, "name") ||
00482       strcmp(reg->regdomain, "namedomain") ||
00483       strcmp(reg->hostname, "domain")     ||
00484       strcmp(reg->authuser, "authuser")           ||
00485       strcmp(reg->secret, "pass")         ||
00486       strcmp(reg->peername, "peer")           ||
00487       reg->transport != SIP_TRANSPORT_TCP ||
00488       reg->timeout != -1                  ||
00489       reg->expire != -1                   ||
00490       reg->refresh != 111 ||
00491       reg->expiry != 111 ||
00492       reg->configured_expiry != 111 ||
00493       reg->portno != 1234    ||
00494       (reg->regdomainport)                ||
00495       reg->callid_valid != FALSE          ||
00496       reg->ocseq != INITIAL_CSEQ) {
00497 
00498       ast_test_status_update(test, "Test 7, change transport to tcp, add custom port, and add peer failed.\n");
00499       res = AST_TEST_FAIL;
00500    }
00501    ast_string_field_free_memory(reg);
00502    ast_free(reg);
00503 
00504    /* ---Test reg 8, remove transport --- */
00505    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00506       goto alloc_fail;
00507    } else if (
00508        sip_parse_register_line(reg, default_expiry, reg8, 1) ||
00509       strcmp(reg->callback, "extension")           ||
00510       strcmp(reg->username, "name") ||
00511       strcmp(reg->regdomain, "namedomain") ||
00512       strcmp(reg->hostname, "domain")     ||
00513       strcmp(reg->authuser, "authuser")           ||
00514       strcmp(reg->secret, "pass")         ||
00515       strcmp(reg->peername, "peer")           ||
00516       reg->transport != SIP_TRANSPORT_UDP ||
00517       reg->timeout != -1                  ||
00518       reg->expire != -1                   ||
00519       reg->refresh != 111 ||
00520       reg->expiry != 111 ||
00521       reg->configured_expiry != 111 ||
00522       reg->portno != 1234    ||
00523       (reg->regdomainport)                ||
00524       reg->callid_valid != FALSE          ||
00525       reg->ocseq != INITIAL_CSEQ) {
00526 
00527       ast_test_status_update(test, "Test 8, remove transport failed.\n");
00528       res = AST_TEST_FAIL;
00529    }
00530    ast_string_field_free_memory(reg);
00531    ast_free(reg);
00532 
00533    /* ---Test reg12, add domain port --- */
00534    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00535       goto alloc_fail;
00536    } else if (
00537       sip_parse_register_line(reg, default_expiry, reg12, 1) ||
00538       strcmp(reg->callback, "s")           ||
00539       strcmp(reg->username, "name") ||
00540       strcmp(reg->regdomain, "namedomain") ||
00541       strcmp(reg->hostname, "domain")     ||
00542       strcmp(reg->authuser, "authuser")           ||
00543       strcmp(reg->secret, "pass")         ||
00544       strcmp(reg->peername, "")           ||
00545       reg->transport != SIP_TRANSPORT_UDP ||
00546       reg->timeout != -1                  ||
00547       reg->expire != -1                   ||
00548       reg->refresh != default_expiry ||
00549       reg->expiry != default_expiry ||
00550       reg->configured_expiry != default_expiry ||
00551       reg->portno != STANDARD_SIP_PORT    ||
00552       reg->regdomainport != 4321          ||
00553       reg->callid_valid != FALSE          ||
00554       reg->ocseq != INITIAL_CSEQ) {
00555 
00556       ast_test_status_update(test, "Test 12, add domain port failed.\n");
00557       res = AST_TEST_FAIL;
00558    }
00559 
00560    /* ---Test reg13, domain port without secret --- */
00561    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00562       goto alloc_fail;
00563    } else if (
00564       sip_parse_register_line(reg, default_expiry, reg13, 1) ||
00565       strcmp(reg->callback, "s")           ||
00566       strcmp(reg->username, "name") ||
00567       strcmp(reg->regdomain, "namedomain") ||
00568       strcmp(reg->hostname, "domain")     ||
00569       strcmp(reg->authuser, "")           ||
00570       strcmp(reg->secret, "")         ||
00571       strcmp(reg->peername, "")           ||
00572       reg->transport != SIP_TRANSPORT_UDP ||
00573       reg->timeout != -1                  ||
00574       reg->expire != -1                   ||
00575       reg->refresh != default_expiry ||
00576       reg->expiry != default_expiry ||
00577       reg->configured_expiry != default_expiry ||
00578       reg->portno != STANDARD_SIP_PORT    ||
00579       reg->regdomainport != 4321          ||
00580       reg->callid_valid != FALSE          ||
00581       reg->ocseq != INITIAL_CSEQ) {
00582 
00583       ast_test_status_update(test, "Test 13, domain port without secret failed.\n");
00584       res = AST_TEST_FAIL;
00585 }
00586 
00587    /* ---Test reg 9, missing domain, expected to fail --- */
00588    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00589       goto alloc_fail;
00590    } else if (!sip_parse_register_line(reg, default_expiry, reg9, 1)) {
00591       ast_test_status_update(test,
00592             "Test 9, missing domain, expected to fail but did not.\n");
00593       res = AST_TEST_FAIL;
00594    }
00595    ast_string_field_free_memory(reg);
00596    ast_free(reg);
00597 
00598    /* ---Test reg 10,  missing user, expected to fail --- */
00599    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00600       goto alloc_fail;
00601    } else if (!sip_parse_register_line(reg, default_expiry, reg10, 1)) {
00602       ast_test_status_update(test,
00603             "Test 10, missing user expected to fail but did not\n");
00604       res = AST_TEST_FAIL;
00605    }
00606    ast_string_field_free_memory(reg);
00607    ast_free(reg);
00608 
00609    /* ---Test reg 11, no registry object, expected to fail--- */
00610    if (!sip_parse_register_line(NULL, default_expiry, reg1, 1)) {
00611       ast_test_status_update(test,
00612             "Test 11, no registry object, expected to fail but did not.\n");
00613       res = AST_TEST_FAIL;
00614    }
00615 
00616    /* ---Test reg 11,  no registry line, expected to fail --- */
00617    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
00618       goto alloc_fail;
00619    } else if (!sip_parse_register_line(reg, default_expiry, NULL, 1)) {
00620 
00621       ast_test_status_update(test,
00622             "Test 11, NULL register line expected to fail but did not.\n");
00623       res = AST_TEST_FAIL;
00624    }
00625    ast_string_field_free_memory(reg);
00626    ast_free(reg);
00627 
00628 
00629    return res;
00630 
00631 alloc_fail:
00632    ast_test_status_update(test, "Out of memory. \n");
00633    return res;
00634 }

void sip_config_parser_register_tests ( void   ) 

SIP test registration.

Definition at line 769 of file config_parser.c.

References AST_TEST_REGISTER.

Referenced by sip_register_tests().

00770 {
00771    AST_TEST_REGISTER(sip_parse_register_line_test);
00772    AST_TEST_REGISTER(sip_parse_host_line_test);
00773 }

void sip_config_parser_unregister_tests ( void   ) 

SIP test registration.

Definition at line 776 of file config_parser.c.

References AST_TEST_UNREGISTER.

Referenced by sip_unregister_tests().

00777 {
00778    AST_TEST_UNREGISTER(sip_parse_register_line_test);
00779    AST_TEST_UNREGISTER(sip_parse_host_line_test);
00780 }

int sip_parse_host ( char *  line,
int  lineno,
char **  hostname,
int *  portnum,
enum sip_transport *  transport 
)

Definition at line 636 of file config_parser.c.

References ast_log(), ast_sockaddr_split_hostport(), ast_strlen_zero(), LOG_NOTICE, and LOG_WARNING.

Referenced by AST_TEST_DEFINE(), and build_peer().

00637 {
00638    char *port;
00639 
00640    if (ast_strlen_zero(line)) {
00641       return -1;
00642    }
00643    if ((*hostname = strstr(line, "://"))) {
00644       *hostname += 3;
00645 
00646       if (!strncasecmp(line, "tcp", 3))
00647          *transport = SIP_TRANSPORT_TCP;
00648       else if (!strncasecmp(line, "tls", 3))
00649          *transport = SIP_TRANSPORT_TLS;
00650       else if (!strncasecmp(line, "udp", 3))
00651          *transport = SIP_TRANSPORT_UDP;
00652       else
00653          ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", line, lineno);
00654    } else {
00655       *hostname = line;
00656       *transport = SIP_TRANSPORT_UDP;
00657    }
00658 
00659    if ((line = strrchr(*hostname, '@')))
00660       line++;
00661    else
00662       line = *hostname;
00663 
00664    if (ast_sockaddr_split_hostport(line, hostname, &port, 0) == 0) {
00665       ast_log(LOG_WARNING, "Cannot parse host '%s' on line %d of sip.conf.\n",
00666          line, lineno);
00667       return -1;
00668    }
00669 
00670    if (port) {
00671       if (!sscanf(port, "%5u", portnum)) {
00672          ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", port, lineno);
00673          port = NULL;
00674       }
00675    }
00676 
00677    if (!port) {
00678       if (*transport & SIP_TRANSPORT_TLS) {
00679          *portnum = STANDARD_TLS_PORT;
00680       } else {
00681          *portnum = STANDARD_SIP_PORT;
00682       }
00683    }
00684 
00685    return 0;
00686 }

int sip_parse_register_line ( struct sip_registry *  reg,
int  default_expiry,
const char *  value,
int  lineno 
)

Parse register=> line in sip.conf.

Return values:
0 on success
-1 on failure

register => [peer?][transport://]user[][:secret[:authuser]][:port][/extension][~expiry] becomes userpart => [peer?][transport://]user[][:secret[:authuser]] hostpart => host[:port][/extension][~expiry]

pre1.peer => peer pre1.userpart => [transport://]user[][:secret[:authuser]] hostpart => host[:port][/extension][~expiry]

pre1.peer => peer pre2.transport = transport pre2.userpart => user[][:secret[:authuser]] hostpart => host[:port][/extension][~expiry]

pre1.peer => peer pre2.transport = transport user1.userpart => user[] user1.secret => secret user1.authuser => authuser hostpart => host[:port][/extension][~expiry]

pre1.peer => peer pre2.transport = transport user1.userpart => user[] user1.secret => secret user1.authuser => authuser host1.hostpart => host[:port][/extension] host1.expiry => [expiry]

pre1.peer => peer pre2.transport = transport user1.userpart => user[] user1.secret => secret user1.authuser => authuser host2.hostpart => host[:port] host2.extension => [extension] host1.expiry => [expiry]

pre1.peer => peer pre2.transport = transport user1.userpart => user[] user1.secret => secret user1.authuser => authuser host3.host => host host3.port => port host2.extension => extension host1.expiry => expiry

pre1.peer => peer pre2.transport = transport user2.user => user user2.domain => domain user1.secret => secret user1.authuser => authuser host3.host => host host3.port => port host2.extension => extension host1.expiry => expiry

pre1.peer => peer pre2.transport = transport user2.user => user user2.domain => domain user1.secret => secret user3.authuser => authuser user3.domainport => domainport host3.host => host host3.port => port host2.extension => extension host1.expiry => expiry

Definition at line 35 of file config_parser.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_string_field_set, ast_strip_quoted(), ast_strlen_zero(), FALSE, hostname, LOG_NOTICE, LOG_WARNING, port_str2int(), S_OR, and secret.

Referenced by AST_TEST_DEFINE(), and sip_register().

00036 {
00037    int portnum = 0;
00038    int domainport = 0;
00039    enum sip_transport transport = SIP_TRANSPORT_UDP;
00040    char buf[256] = "";
00041    char *userpart = NULL, *hostpart = NULL;
00042    /* register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] */
00043    AST_DECLARE_APP_ARGS(pre1,
00044       AST_APP_ARG(peer);
00045       AST_APP_ARG(userpart);
00046    );
00047    AST_DECLARE_APP_ARGS(pre2,
00048       AST_APP_ARG(transport);
00049       AST_APP_ARG(blank);
00050       AST_APP_ARG(userpart);
00051    );
00052    AST_DECLARE_APP_ARGS(user1,
00053       AST_APP_ARG(userpart);
00054       AST_APP_ARG(secret);
00055       AST_APP_ARG(authuser);
00056    );
00057    AST_DECLARE_APP_ARGS(user2,
00058       AST_APP_ARG(user);
00059       AST_APP_ARG(domain);
00060    );
00061    AST_DECLARE_APP_ARGS(user3,
00062       AST_APP_ARG(authuser);
00063       AST_APP_ARG(domainport);
00064    );
00065    AST_DECLARE_APP_ARGS(host1,
00066       AST_APP_ARG(hostpart);
00067       AST_APP_ARG(expiry);
00068    );
00069    AST_DECLARE_APP_ARGS(host2,
00070       AST_APP_ARG(hostpart);
00071       AST_APP_ARG(extension);
00072    );
00073    AST_DECLARE_APP_ARGS(host3,
00074       AST_APP_ARG(host);
00075       AST_APP_ARG(port);
00076    );
00077 
00078    if (!value) {
00079       return -1;
00080    }
00081 
00082    if (!reg) {
00083       return -1;
00084    }
00085    ast_copy_string(buf, value, sizeof(buf));
00086 
00087    /*! register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry]
00088     * becomes
00089     *   userpart => [peer?][transport://]user[@domain][:secret[:authuser]]
00090     *   hostpart => host[:port][/extension][~expiry]
00091     */
00092    if ((hostpart = strrchr(buf, '@'))) {
00093       *hostpart++ = '\0';
00094       userpart = buf;
00095    }
00096 
00097    if (ast_strlen_zero(userpart) || ast_strlen_zero(hostpart)) {
00098       ast_log(LOG_WARNING, "Format for registration is [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] at line %d\n", lineno);
00099       return -1;
00100    }
00101 
00102    /*!
00103     * pre1.peer => peer
00104     * pre1.userpart => [transport://]user[@domain][:secret[:authuser]]
00105     * hostpart => host[:port][/extension][~expiry]
00106     */
00107    AST_NONSTANDARD_RAW_ARGS(pre1, userpart, '?');
00108    if (ast_strlen_zero(pre1.userpart)) {
00109       pre1.userpart = pre1.peer;
00110       pre1.peer = NULL;
00111    }
00112 
00113    /*!
00114     * pre1.peer => peer
00115     * pre2.transport = transport
00116     * pre2.userpart => user[@domain][:secret[:authuser]]
00117     * hostpart => host[:port][/extension][~expiry]
00118     */
00119    AST_NONSTANDARD_RAW_ARGS(pre2, pre1.userpart, '/');
00120    if (ast_strlen_zero(pre2.userpart)) {
00121       pre2.userpart = pre2.transport;
00122       pre2.transport = NULL;
00123    } else {
00124       pre2.transport[strlen(pre2.transport) - 1] = '\0'; /* Remove trailing : */
00125    }
00126 
00127    if (!ast_strlen_zero(pre2.blank)) {
00128       ast_log(LOG_WARNING, "Format for registration is [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] at line %d\n", lineno);
00129       return -1;
00130    }
00131 
00132    /*!
00133     * pre1.peer => peer
00134     * pre2.transport = transport
00135     * user1.userpart => user[@domain]
00136     * user1.secret => secret
00137     * user1.authuser => authuser
00138     * hostpart => host[:port][/extension][~expiry]
00139     */
00140    AST_NONSTANDARD_RAW_ARGS(user1, pre2.userpart, ':');
00141 
00142    /*!
00143     * pre1.peer => peer
00144     * pre2.transport = transport
00145     * user1.userpart => user[@domain]
00146     * user1.secret => secret
00147     * user1.authuser => authuser
00148     * host1.hostpart => host[:port][/extension]
00149     * host1.expiry => [expiry]
00150     */
00151    AST_NONSTANDARD_RAW_ARGS(host1, hostpart, '~');
00152 
00153    /*!
00154     * pre1.peer => peer
00155     * pre2.transport = transport
00156     * user1.userpart => user[@domain]
00157     * user1.secret => secret
00158     * user1.authuser => authuser
00159     * host2.hostpart => host[:port]
00160     * host2.extension => [extension]
00161     * host1.expiry => [expiry]
00162     */
00163    AST_NONSTANDARD_RAW_ARGS(host2, host1.hostpart, '/');
00164 
00165    /*!
00166     * pre1.peer => peer
00167     * pre2.transport = transport
00168     * user1.userpart => user[@domain]
00169     * user1.secret => secret
00170     * user1.authuser => authuser
00171     * host3.host => host
00172     * host3.port => port
00173     * host2.extension => extension
00174     * host1.expiry => expiry
00175     */
00176    AST_NONSTANDARD_RAW_ARGS(host3, host2.hostpart, ':');
00177 
00178    /*!
00179      * pre1.peer => peer
00180      * pre2.transport = transport
00181      * user2.user => user
00182      * user2.domain => domain
00183      * user1.secret => secret
00184      * user1.authuser => authuser
00185      * host3.host => host
00186      * host3.port => port
00187      * host2.extension => extension
00188      * host1.expiry => expiry
00189     */
00190    AST_NONSTANDARD_RAW_ARGS(user2, user1.userpart, '@');
00191 
00192    /*!
00193      * pre1.peer => peer
00194      * pre2.transport = transport
00195      * user2.user => user
00196      * user2.domain => domain
00197      * user1.secret => secret
00198      * user3.authuser => authuser
00199      * user3.domainport => domainport
00200      * host3.host => host
00201      * host3.port => port
00202      * host2.extension => extension
00203      * host1.expiry => expiry
00204     */
00205    AST_NONSTANDARD_RAW_ARGS(user3, user1.authuser, ':');
00206 
00207    /* Reordering needed due to fields being [(:secret[:username])|(:regdomainport:secret:username)]
00208       but parsing being [secret[:username[:regdomainport]]] */
00209    if (user3.argc == 2) {
00210       char *reorder = user3.domainport;
00211       user3.domainport = user1.secret;
00212       user1.secret = user3.authuser;
00213       user3.authuser = reorder;
00214    }
00215 
00216    if (host3.port) {
00217       if (!(portnum = port_str2int(host3.port, 0))) {
00218          ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", host3.port, lineno);
00219       }
00220    }
00221    if (user3.domainport) {
00222       if (!(domainport = port_str2int(user3.domainport, 0))) {
00223          ast_log(LOG_NOTICE, "'%s' is not a valid domain port number on line %d of sip.conf. using default.\n", user3.domainport, lineno);
00224       }
00225    }
00226 
00227    /* set transport type */
00228    if (!pre2.transport) {
00229       transport = SIP_TRANSPORT_UDP;
00230    } else if (!strncasecmp(pre2.transport, "tcp", 3)) {
00231       transport = SIP_TRANSPORT_TCP;
00232    } else if (!strncasecmp(pre2.transport, "tls", 3)) {
00233       transport = SIP_TRANSPORT_TLS;
00234    } else if (!strncasecmp(pre2.transport, "udp", 3)) {
00235       transport = SIP_TRANSPORT_UDP;
00236    } else {
00237       transport = SIP_TRANSPORT_UDP;
00238       ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", pre2.transport, lineno);
00239    }
00240 
00241    /* if no portnum specified, set default for transport */
00242    if (!portnum) {
00243       if (transport == SIP_TRANSPORT_TLS) {
00244          portnum = STANDARD_TLS_PORT;
00245       } else {
00246          portnum = STANDARD_SIP_PORT;
00247       }
00248    }
00249 
00250    /* copy into sip_registry object */
00251    ast_string_field_set(reg, callback, ast_strip_quoted(S_OR(host2.extension, "s"), "\"", "\""));
00252    ast_string_field_set(reg, username, ast_strip_quoted(S_OR(user2.user, ""), "\"", "\""));
00253    ast_string_field_set(reg, hostname, ast_strip_quoted(S_OR(host3.host, ""), "\"", "\""));
00254    ast_string_field_set(reg, authuser, ast_strip_quoted(S_OR(user3.authuser, ""), "\"", "\""));
00255    ast_string_field_set(reg, secret, ast_strip_quoted(S_OR(user1.secret, ""), "\"", "\""));
00256    ast_string_field_set(reg, peername, ast_strip_quoted(S_OR(pre1.peer, ""), "\"", "\""));
00257    ast_string_field_set(reg, regdomain, ast_strip_quoted(S_OR(user2.domain, ""), "\"", "\""));
00258 
00259    reg->transport = transport;
00260    reg->timeout = reg->expire = -1;
00261    reg->portno = portnum;
00262    reg->regdomainport = domainport;
00263    reg->callid_valid = FALSE;
00264    reg->ocseq = INITIAL_CSEQ;
00265    reg->refresh = reg->expiry = reg->configured_expiry = (host1.expiry ? atoi(ast_strip_quoted(host1.expiry, "\"", "\"")) : default_expiry);
00266 
00267    return 0;
00268 }


Generated on Mon Mar 19 11:30:46 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7