[asterisk-commits] oej: branch oej/codename-pineapple r46388 - in
/team/oej/codename-pineapple/c...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sat Oct 28 13:06:53 MST 2006
Author: oej
Date: Sat Oct 28 15:06:52 2006
New Revision: 46388
URL: http://svn.digium.com/view/asterisk?rev=46388&view=rev
Log:
Moving around
Modified:
team/oej/codename-pineapple/channels/chan_sip3.c
team/oej/codename-pineapple/channels/sip3/sip3_compose.c
team/oej/codename-pineapple/channels/sip3/sip3funcs.h
Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?rev=46388&r1=46387&r2=46388&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Sat Oct 28 15:06:52 2006
@@ -491,14 +491,10 @@
static void free_old_route(struct sip_route *route);
/*--- Constructing requests and responses */
-static int reqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch);
static void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod);
static int init_resp(struct sip_request *resp, const char *msg);
-static int respprep(struct sip_request *resp, struct sip_dialog *p, const char *msg, const struct sip_request *req);
static int create_addr_from_peer(struct sip_dialog *r, struct sip_peer *peer);
static int add_vidupdate(struct sip_request *req);
-static void add_route(struct sip_request *req, struct sip_route *route);
-static void set_destination(struct sip_dialog *p, char *uri);
static void build_rpid(struct sip_dialog *p);
/*------Request handling functions */
@@ -2096,121 +2092,6 @@
return add_header(req, "Content-Length", clen);
}
-/*! \brief Add content (not header) to SIP message */
-GNURK int add_line(struct sip_request *req, const char *line)
-{
- if (req->lines == SIP_MAX_LINES) {
- ast_log(LOG_WARNING, "Out of SIP line space\n");
- return -1;
- }
- if (!req->lines) {
- /* Add extra empty return */
- snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
- req->len += strlen(req->data + req->len);
- }
- if (req->len >= sizeof(req->data) - 4) {
- ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
- return -1;
- }
- req->line[req->lines] = req->data + req->len;
- snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
- req->len += strlen(req->line[req->lines]);
- req->lines++;
- return 0;
-}
-
-/*! \brief Add route header into request per learned route */
-static void add_route(struct sip_request *req, struct sip_route *route)
-{
- char r[BUFSIZ*2], *p;
- int n, rem = sizeof(r);
-
- if (!route)
- return;
-
- p = r;
- for (;route ; route = route->next) {
- n = strlen(route->hop);
- if (rem < n+3) /* we need room for ",<route>" */
- break;
- if (p != r) { /* add a separator after fist route */
- *p++ = ',';
- --rem;
- }
- *p++ = '<';
- ast_copy_string(p, route->hop, rem); /* cannot fail */
- p += n;
- *p++ = '>';
- rem -= (n+2);
- }
- *p = '\0';
- add_header(req, "Route", r);
-}
-
-/*! \brief Set destination from SIP URI */
-static void set_destination(struct sip_dialog *p, char *uri)
-{
- char *h, *maddr, hostname[256];
- int port, hn;
- struct hostent *hp;
- struct ast_hostent ahp;
- int debug=sip_debug_test_pvt(p);
-
- /* Parse uri to h (host) and port - uri is already just the part inside the <> */
- /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
-
- if (debug)
- ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
-
- /* Find and parse hostname */
- h = strchr(uri, '@');
- if (h)
- ++h;
- else {
- h = uri;
- if (strncmp(h, "sip:", 4) == 0)
- h += 4;
- else if (strncmp(h, "sips:", 5) == 0)
- h += 5;
- }
- hn = strcspn(h, ":;>") + 1;
- if (hn > sizeof(hostname))
- hn = sizeof(hostname);
- ast_copy_string(hostname, h, hn);
- /* XXX bug here if string has been trimmed to sizeof(hostname) */
- h += hn - 1;
-
- /* Is "port" present? if not default to STANDARD_SIP_PORT */
- if (*h == ':') {
- /* Parse port */
- ++h;
- port = strtol(h, &h, 10);
- }
- else
- port = STANDARD_SIP_PORT;
-
- /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
- maddr = strstr(h, "maddr=");
- if (maddr) {
- maddr += 6;
- hn = strspn(maddr, "0123456789.") + 1;
- if (hn > sizeof(hostname))
- hn = sizeof(hostname);
- ast_copy_string(hostname, maddr, hn);
- }
-
- hp = ast_gethostbyname(hostname, &ahp);
- if (hp == NULL) {
- ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
- return;
- }
- p->sa.sin_family = AF_INET;
- memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
- p->sa.sin_port = htons(port);
- if (debug)
- ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
-}
-
/*! \brief Initialize SIP response, based on SIP request */
static int init_resp(struct sip_request *resp, const char *msg)
{
@@ -2234,154 +2115,6 @@
snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_method2txt(sipmethod), recip);
req->len = strlen(req->header[0]);
req->headers++;
- return 0;
-}
-
-
-/*! \brief Prepare SIP response packet */
-static int respprep(struct sip_request *resp, struct sip_dialog *p, const char *msg, const struct sip_request *req)
-{
- char newto[256];
- const char *ot;
-
- init_resp(resp, msg);
- copy_via_headers(p, resp, req, "Via");
- if (msg[0] == '2')
- copy_all_header(resp, req, "Record-Route");
- copy_header(resp, req, "From");
- ot = get_header(req, "To");
- if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
- /* Add the proper tag if we don't have it already. If they have specified
- their tag, use it. Otherwise, use our own tag */
- if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
- else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
- else
- ast_copy_string(newto, ot, sizeof(newto));
- ot = newto;
- }
- add_header(resp, "To", ot);
- copy_header(resp, req, "Call-ID");
- copy_header(resp, req, "CSeq");
- add_header(resp, "User-Agent", global.useragent);
- add_header(resp, "Allow", ALLOWED_METHODS);
- add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
- if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
- /* For registration responses, we also need expiry and
- contact info */
- char tmp[256];
-
- snprintf(tmp, sizeof(tmp), "%d", p->expiry);
- add_header(resp, "Expires", tmp);
- if (p->expiry) { /* Only add contact if we have an expiry time */
- char contact[256];
- snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
- add_header(resp, "Contact", contact); /* Not when we unregister */
- }
- } else if (msg[0] != '4' && p->our_contact[0]) {
- add_header(resp, "Contact", p->our_contact);
- }
- return 0;
-}
-
-/*! \brief Initialize a SIP request message (not the initial one in a dialog) */
-static int reqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch)
-{
- struct sip_request *orig = &p->initreq;
- char stripped[80];
- char tmp[80];
- char newto[256];
- const char *c;
- const char *ot, *of;
- int is_strict = FALSE; /*!< Strict routing flag */
-
- memset(req, 0, sizeof(struct sip_request));
-
- snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_method2txt(sipmethod));
-
- if (!seqno) {
- p->ocseq++;
- seqno = p->ocseq;
- }
-
- if (newbranch) {
- p->branch ^= ast_random();
- build_via(p);
- }
-
- /* Check for strict or loose router */
- if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
- is_strict = TRUE;
- if (sipdebug)
- ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
- }
-
- if (sipmethod == SIP_CANCEL)
- c = p->initreq.rlPart2; /* Use original URI */
- else if (sipmethod == SIP_ACK) {
- /* Use URI from Contact: in 200 OK (if INVITE)
- (we only have the contacturi on INVITEs) */
- if (!ast_strlen_zero(p->okcontacturi))
- c = is_strict ? p->route->hop : p->okcontacturi;
- else
- c = p->initreq.rlPart2;
- } else if (!ast_strlen_zero(p->okcontacturi))
- c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
- else if (!ast_strlen_zero(p->uri))
- c = p->uri;
- else {
- char *n;
- /* We have no URI, use To: or From: header as URI (depending on direction) */
- ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
- sizeof(stripped));
- n = get_in_brackets(stripped);
- c = strsep(&n, ";"); /* trim ; and beyond */
- }
- init_req(req, sipmethod, c);
-
- snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_method2txt(sipmethod));
-
- add_header(req, "Via", p->via);
- if (p->route) {
- set_destination(p, p->route->hop);
- add_route(req, is_strict ? p->route->next : p->route);
- }
-
- ot = get_header(orig, "To");
- of = get_header(orig, "From");
-
- /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
- as our original request, including tag (or presumably lack thereof) */
- if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
- /* Add the proper tag if we don't have it already. If they have specified
- their tag, use it. Otherwise, use our own tag */
- if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
- else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
- snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
- else
- snprintf(newto, sizeof(newto), "%s", ot);
- ot = newto;
- }
-
- if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
- add_header(req, "From", of);
- add_header(req, "To", ot);
- } else {
- add_header(req, "From", ot);
- add_header(req, "To", of);
- }
- add_header(req, "Contact", p->our_contact);
- copy_header(req, orig, "Call-ID");
- add_header(req, "CSeq", tmp);
-
- add_header(req, "User-Agent", global.useragent);
- add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
-
- if (!ast_strlen_zero(p->rpid))
- add_header(req, "Remote-Party-ID", p->rpid);
-
return 0;
}
Modified: team/oej/codename-pineapple/channels/sip3/sip3_compose.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_compose.c?rev=46388&r1=46387&r2=46388&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_compose.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_compose.c Sat Oct 28 15:06:52 2006
@@ -132,3 +132,268 @@
return 0;
}
+/*! \brief Prepare SIP response packet */
+int respprep(struct sip_request *resp, struct sip_dialog *p, const char *msg, const struct sip_request *req)
+{
+ char newto[256];
+ const char *ot;
+
+ init_resp(resp, msg);
+ copy_via_headers(p, resp, req, "Via");
+ if (msg[0] == '2')
+ copy_all_header(resp, req, "Record-Route");
+ copy_header(resp, req, "From");
+ ot = get_header(req, "To");
+ if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
+ /* Add the proper tag if we don't have it already. If they have specified
+ their tag, use it. Otherwise, use our own tag */
+ if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
+ snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
+ else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
+ snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
+ else
+ ast_copy_string(newto, ot, sizeof(newto));
+ ot = newto;
+ }
+ add_header(resp, "To", ot);
+ copy_header(resp, req, "Call-ID");
+ copy_header(resp, req, "CSeq");
+ add_header(resp, "User-Agent", global.useragent);
+ add_header(resp, "Allow", ALLOWED_METHODS);
+ add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
+ if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
+ /* For successful registration responses, we also need expiry and
+ contact info */
+ char tmp[256];
+
+ snprintf(tmp, sizeof(tmp), "%d", p->expiry);
+ add_header(resp, "Expires", tmp);
+ if (p->expiry) { /* Only add contact if we have an expiry time */
+ char contact[256];
+ snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry);
+ add_header(resp, "Contact", contact); /* Not when we unregister */
+ }
+ } else if (msg[0] != '4' && p->our_contact[0]) {
+ add_header(resp, "Contact", p->our_contact);
+ }
+ return 0;
+}
+
+/*! \brief Add route header into request per learned route */
+void add_route(struct sip_request *req, struct sip_route *route)
+{
+ char r[BUFSIZ*2], *p;
+ int n, rem = sizeof(r);
+
+ if (!route)
+ return;
+
+ p = r;
+ for (;route ; route = route->next) {
+ n = strlen(route->hop);
+ if (rem < n+3) /* we need room for ",<route>" */
+ break;
+ if (p != r) { /* add a separator after fist route */
+ *p++ = ',';
+ --rem;
+ }
+ *p++ = '<';
+ ast_copy_string(p, route->hop, rem); /* cannot fail */
+ p += n;
+ *p++ = '>';
+ rem -= (n+2);
+ }
+ *p = '\0';
+ add_header(req, "Route", r);
+}
+
+/*! \brief Add content (not header) to SIP message */
+int add_line(struct sip_request *req, const char *line)
+{
+ if (req->lines == SIP_MAX_LINES) {
+ ast_log(LOG_WARNING, "Out of SIP line space\n");
+ return -1;
+ }
+ if (!req->lines) {
+ /* Add extra empty return */
+ snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
+ req->len += strlen(req->data + req->len);
+ }
+ if (req->len >= sizeof(req->data) - 4) {
+ ast_log(LOG_WARNING, "Out of space, can't add anymore\n");
+ return -1;
+ }
+ req->line[req->lines] = req->data + req->len;
+ snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);
+ req->len += strlen(req->line[req->lines]);
+ req->lines++;
+ return 0;
+}
+
+/*! \brief Set destination from SIP URI */
+static void set_destination(struct sip_dialog *p, char *uri)
+{
+ char *h, *maddr, hostname[256];
+ int port, hn;
+ struct hostent *hp;
+ struct ast_hostent ahp;
+ int debug=sip_debug_test_pvt(p);
+
+ /* Parse uri to h (host) and port - uri is already just the part inside the <> */
+ /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
+
+ if (debug)
+ ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
+
+ /* Find and parse hostname */
+ h = strchr(uri, '@');
+ if (h)
+ ++h;
+ else {
+ h = uri;
+ if (strncmp(h, "sip:", 4) == 0)
+ h += 4;
+ else if (strncmp(h, "sips:", 5) == 0)
+ h += 5;
+ }
+ hn = strcspn(h, ":;>") + 1;
+ if (hn > sizeof(hostname))
+ hn = sizeof(hostname);
+ ast_copy_string(hostname, h, hn);
+ /* XXX bug here if string has been trimmed to sizeof(hostname) */
+ h += hn - 1;
+
+ /* Is "port" present? if not default to STANDARD_SIP_PORT */
+ if (*h == ':') {
+ /* Parse port */
+ ++h;
+ port = strtol(h, &h, 10);
+ }
+ else
+ port = STANDARD_SIP_PORT;
+
+ /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
+ maddr = strstr(h, "maddr=");
+ if (maddr) {
+ maddr += 6;
+ hn = strspn(maddr, "0123456789.") + 1;
+ if (hn > sizeof(hostname))
+ hn = sizeof(hostname);
+ ast_copy_string(hostname, maddr, hn);
+ }
+
+ hp = ast_gethostbyname(hostname, &ahp);
+ if (hp == NULL) {
+ ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
+ return;
+ }
+ p->sa.sin_family = AF_INET;
+ memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
+ p->sa.sin_port = htons(port);
+ if (debug)
+ ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
+}
+
+
+/*! \brief Initialize a SIP request message (not the initial one in a dialog) */
+int reqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch)
+{
+ struct sip_request *orig = &p->initreq;
+ char stripped[80];
+ char tmp[80];
+ char newto[256];
+ const char *c;
+ const char *ot, *of;
+ int is_strict = FALSE; /*!< Strict routing flag */
+
+ memset(req, 0, sizeof(struct sip_request));
+
+ snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_method2txt(sipmethod));
+
+ if (!seqno) {
+ p->ocseq++;
+ seqno = p->ocseq;
+ }
+
+ if (newbranch) {
+ p->branch ^= ast_random();
+ build_via(p);
+ }
+
+ /* Check for strict or loose router */
+ if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) {
+ is_strict = TRUE;
+ if (sipdebug)
+ ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid);
+ }
+
+ if (sipmethod == SIP_CANCEL)
+ c = p->initreq.rlPart2; /* Use original URI */
+ else if (sipmethod == SIP_ACK) {
+ /* Use URI from Contact: in 200 OK (if INVITE)
+ (we only have the contacturi on INVITEs) */
+ if (!ast_strlen_zero(p->okcontacturi))
+ c = is_strict ? p->route->hop : p->okcontacturi;
+ else
+ c = p->initreq.rlPart2;
+ } else if (!ast_strlen_zero(p->okcontacturi))
+ c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
+ else if (!ast_strlen_zero(p->uri))
+ c = p->uri;
+ else {
+ char *n;
+ /* We have no URI, use To: or From: header as URI (depending on direction) */
+ ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"),
+ sizeof(stripped));
+ n = get_in_brackets(stripped);
+ c = strsep(&n, ";"); /* trim ; and beyond */
+ }
+ init_req(req, sipmethod, c);
+
+ snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_method2txt(sipmethod));
+
+ add_header(req, "Via", p->via);
+ if (p->route) {
+ set_destination(p, p->route->hop);
+ add_route(req, is_strict ? p->route->next : p->route);
+ }
+
+ ot = get_header(orig, "To");
+ of = get_header(orig, "From");
+
+ /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
+ as our original request, including tag (or presumably lack thereof) */
+ if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
+ /* Add the proper tag if we don't have it already. If they have specified
+ their tag, use it. Otherwise, use our own tag */
+ if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag))
+ snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
+ else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING))
+ snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
+ else
+ snprintf(newto, sizeof(newto), "%s", ot);
+ ot = newto;
+ }
+
+ if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
+ add_header(req, "From", of);
+ add_header(req, "To", ot);
+ } else {
+ add_header(req, "From", ot);
+ add_header(req, "To", of);
+ }
+ add_header(req, "Contact", p->our_contact);
+ copy_header(req, orig, "Call-ID");
+ add_header(req, "CSeq", tmp);
+
+ add_header(req, "User-Agent", global.useragent);
+ add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
+
+ if (!ast_strlen_zero(p->rpid))
+ add_header(req, "Remote-Party-ID", p->rpid);
+
+ return 0;
+}
+
+
+
Modified: team/oej/codename-pineapple/channels/sip3/sip3funcs.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3funcs.h?rev=46388&r1=46387&r2=46388&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3funcs.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3funcs.h Sat Oct 28 15:06:52 2006
@@ -56,7 +56,6 @@
GNURK void destroy_association(struct sip_peer *peer);
GNURK void reg_source_db(struct sip_peer *peer);
GNURK int expire_register(void *data);
-GNURK int add_line(struct sip_request *req, const char *line);
GNURK int sip_do_relaod(enum channelreloadreason reason);
GNURK inline int sip_debug_test_addr(const struct sockaddr_in *addr);
GNURK void parse_request(struct sip_request *req);
@@ -129,6 +128,10 @@
GNURK void append_date(struct sip_request *req);
GNURK int add_text(struct sip_request *req, const char *text);
GNURK int add_digit(struct sip_request *req, char digit);
+GNURK int respprep(struct sip_request *resp, struct sip_dialog *p, const char *msg, const struct sip_request *req);
+GNURK void add_route(struct sip_request *req, struct sip_route *route);
+GNURK int add_line(struct sip_request *req, const char *line);
+GNURK int reqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch);
/*! sip3_domain.c: Domain handling functions (sip domain hosting, not DNS lookups) */
GNURK int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context);
More information about the asterisk-commits
mailing list