Sat Aug 6 00:39:55 2011

Asterisk developer's documentation


enum.h File Reference

DNS and ENUM functions. More...

#include "asterisk/channel.h"

Go to the source code of this file.

Functions

int ast_enum_init (void)
 Initialize the ENUM support subsystem.
int ast_enum_reload (void)
int ast_get_enum (struct ast_channel *chan, const char *number, char *location, int maxloc, char *technology, int maxtech, char *suffix, char *options, unsigned int record)
 Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup.
int ast_get_txt (struct ast_channel *chan, const char *number, char *location, int maxloc, char *technology, int maxtech, char *txt, int maxtxt)
 Lookup DNS TXT record (used by app TXTCIDnum.


Detailed Description

DNS and ENUM functions.

Definition in file enum.h.


Function Documentation

int ast_enum_init ( void   ) 

Initialize the ENUM support subsystem.

Definition at line 646 of file enum.c.

References ast_config_destroy(), ast_config_load(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), enum_newtoplev(), enumlock, free, ast_variable::name, ast_variable::next, s, TOPLEV, toplevs, and ast_variable::value.

Referenced by ast_enum_reload(), and main().

00647 {
00648    struct ast_config *cfg;
00649    struct enum_search *s, *sl;
00650    struct ast_variable *v;
00651 
00652    /* Destroy existing list */
00653    ast_mutex_lock(&enumlock);
00654    s = toplevs;
00655    while(s) {
00656       sl = s;
00657       s = s->next;
00658       free(sl);
00659    }
00660    toplevs = NULL;
00661    cfg = ast_config_load("enum.conf");
00662    if (cfg) {
00663       sl = NULL;
00664       v = ast_variable_browse(cfg, "general");
00665       while(v) {
00666          if (!strcasecmp(v->name, "search")) {
00667             s = enum_newtoplev(v->value);
00668             if (s) {
00669                if (sl)
00670                   sl->next = s;
00671                else
00672                   toplevs = s;
00673                sl = s;
00674             }
00675          }
00676          v = v->next;
00677       }
00678       ast_config_destroy(cfg);
00679    } else {
00680       toplevs = enum_newtoplev(TOPLEV);
00681    }
00682    enumver++;
00683    ast_mutex_unlock(&enumlock);
00684    return 0;
00685 }

int ast_enum_reload ( void   ) 

Definition at line 687 of file enum.c.

References ast_enum_init().

00688 {
00689    return ast_enum_init();
00690 }

int ast_get_enum ( struct ast_channel chan,
const char *  number,
char *  location,
int  maxloc,
char *  technology,
int  maxtech,
char *  suffix,
char *  options,
unsigned int  record 
)

Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup.

Parameters:
chan Channel
number E164 number with or without the leading +
location Number returned (or SIP uri)
maxloc Max length
technology Technology (from url scheme in response) You can set it to get particular answer RR, if there are many techs in DNS response, example: "sip" If you need any record, then set it to empty string
maxtech Max length
suffix Zone suffix (if is NULL then use enum.conf 'search' variable)
options Options ('c' to count number of NAPTR RR)
record The position of required RR in the answer list

Definition at line 409 of file enum.c.

References ast_autoservice_start(), ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enum_callback(), enumlock, ENUMLOOKUP_OPTIONS_COUNT, errno, LOG_DEBUG, enum_context::naptrinput, s, and toplevs.

Referenced by function_enum().

00410 {
00411    struct enum_context context;
00412    char tmp[259 + 512];
00413    char naptrinput[512];
00414    int pos = strlen(number) - 1;
00415    int newpos = 0;
00416    int ret = -1;
00417    struct enum_search *s = NULL;
00418    int version = -1;
00419    /* for ISN rewrite */
00420    char *p1 = NULL;
00421    char *p2 = NULL;
00422    int k = 0;
00423    int i = 0;
00424    int z = 0;
00425 
00426    ast_copy_string(naptrinput, number[0] == 'n' ? number+1 : number, sizeof(naptrinput));
00427 
00428    context.naptrinput = naptrinput; /* The number */
00429    context.dst = dst;         /* Return string */
00430    context.dstlen = dstlen;
00431    context.tech = tech;
00432    context.techlen = techlen;
00433    context.options = 0;
00434    context.position = record > 0 ? record : 1;
00435    context.naptr_rrs = NULL;
00436    context.naptr_rrs_count = 0;
00437 
00438    if (options != NULL) {
00439       if (*options == 'c') {
00440          context.options = ENUMLOOKUP_OPTIONS_COUNT;
00441          context.position = 0;
00442       }
00443    }
00444 
00445    ast_log(LOG_DEBUG, "ast_get_enum(): n='%s', tech='%s', suffix='%s', options='%d', record='%d'\n",
00446          number, tech, suffix, context.options, context.position);
00447 
00448    if (pos > 128)
00449       pos = 128;
00450 
00451    /* ISN rewrite */
00452    p1 = strchr(number, '*');
00453 
00454    if (number[0] == 'n') { /* do not perform ISN rewrite ('n' is testing flag) */
00455       p1 = NULL;
00456       k = 1; /* strip 'n' from number */
00457    }
00458 
00459    if (p1 != NULL) {
00460       p2 = p1+1;
00461       while (p1 > number){
00462          p1--;
00463          tmp[newpos++] = *p1;
00464          tmp[newpos++] = '.';
00465       }
00466       if (*p2) {
00467          while(*p2 && newpos < 128){
00468             tmp[newpos++] = *p2;
00469             p2++;
00470          }
00471          tmp[newpos++] = '.';
00472       }
00473 
00474    } else {
00475       while (pos >= k) {
00476          if (isdigit(number[pos])) {
00477             tmp[newpos++] = number[pos];
00478             tmp[newpos++] = '.';
00479          }
00480          pos--;
00481       }
00482    }
00483 
00484    if (chan && ast_autoservice_start(chan) < 0)
00485       return -1;
00486 
00487    if(suffix) {
00488       ast_copy_string(tmp + newpos, suffix, sizeof(tmp) - newpos);
00489       ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
00490       ast_log(LOG_DEBUG, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret);
00491    } else {
00492       ret = -1;      /* this is actually dead code since the demise of app_enum.c */
00493       for (;;) {
00494          ast_mutex_lock(&enumlock);
00495          if (version != enumver) {
00496             /* Ooh, a reload... */
00497             s = toplevs;
00498             version = enumver;
00499          } else {
00500             s = s->next;
00501          }
00502          ast_mutex_unlock(&enumlock);
00503 
00504          if (!s)
00505             break;
00506    
00507          ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos);
00508          ret = ast_search_dns(&context, tmp, C_IN, T_NAPTR, enum_callback);
00509          ast_log(LOG_DEBUG, "ast_get_enum: ast_search_dns(%s) returned %d\n", tmp, ret);
00510          if (ret > 0)
00511             break;
00512       }
00513    }
00514 
00515    if (ret < 0) {
00516       ast_log(LOG_DEBUG, "No such number found: %s (%s)\n", tmp, strerror(errno));
00517       strcpy(dst, "0");
00518       ret = 0;
00519    }
00520 
00521    if (context.naptr_rrs_count >= context.position && ! (context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00522       /* sort array by NAPTR order/preference */
00523       for (k = 0; k < context.naptr_rrs_count; k++) {
00524          for (i = 0; i < context.naptr_rrs_count; i++) {
00525             /* use order first and then preference to compare */
00526             if ((ntohs(context.naptr_rrs[k].naptr.order) < ntohs(context.naptr_rrs[i].naptr.order)
00527                   && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00528                || (ntohs(context.naptr_rrs[k].naptr.order) > ntohs(context.naptr_rrs[i].naptr.order)
00529                   && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00530                z = context.naptr_rrs[k].sort_pos;
00531                context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00532                context.naptr_rrs[i].sort_pos = z;
00533                continue;
00534             }
00535             if (ntohs(context.naptr_rrs[k].naptr.order) == ntohs(context.naptr_rrs[i].naptr.order)) {
00536                if ((ntohs(context.naptr_rrs[k].naptr.pref) < ntohs(context.naptr_rrs[i].naptr.pref)
00537                      && context.naptr_rrs[k].sort_pos > context.naptr_rrs[i].sort_pos)
00538                   || (ntohs(context.naptr_rrs[k].naptr.pref) > ntohs(context.naptr_rrs[i].naptr.pref)
00539                      && context.naptr_rrs[k].sort_pos < context.naptr_rrs[i].sort_pos)){
00540                   z = context.naptr_rrs[k].sort_pos;
00541                   context.naptr_rrs[k].sort_pos = context.naptr_rrs[i].sort_pos;
00542                   context.naptr_rrs[i].sort_pos = z;
00543                }
00544             }
00545          }
00546       }
00547       for (k = 0; k < context.naptr_rrs_count; k++) {
00548          if (context.naptr_rrs[k].sort_pos == context.position-1) {
00549             ast_copy_string(context.dst, context.naptr_rrs[k].result, dstlen);
00550             ast_copy_string(context.tech, context.naptr_rrs[k].tech, techlen);
00551             break;
00552          }
00553       }
00554    } else if (!(context.options & ENUMLOOKUP_OPTIONS_COUNT)) {
00555       context.dst[0] = 0;
00556    }
00557    if (chan)
00558       ret |= ast_autoservice_stop(chan);
00559 
00560    for (k = 0; k < context.naptr_rrs_count; k++) {
00561       free(context.naptr_rrs[k].result);
00562       free(context.naptr_rrs[k].tech);
00563    }
00564 
00565    free(context.naptr_rrs);
00566 
00567    return ret;
00568 }

int ast_get_txt ( struct ast_channel chan,
const char *  number,
char *  location,
int  maxloc,
char *  technology,
int  maxtech,
char *  txt,
int  maxtxt 
)

Lookup DNS TXT record (used by app TXTCIDnum.

Parameters:
chan Channel
number E164 number with or without the leading +
location Number returned (or SIP uri)
maxloc Max length of number
technology Technology (not used in TXT records)
maxtech Max length
txt Text string (return value)
maxtxt Max length of "txt"

Definition at line 573 of file enum.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enumlock, errno, LOG_DEBUG, enum_context::naptrinput, option_debug, s, toplevs, and txt_callback().

Referenced by function_txtcidname().

00574 {
00575    struct enum_context context;
00576    char tmp[259 + 512];
00577    char naptrinput[512] = "+";
00578    int pos = strlen(number) - 1;
00579    int newpos = 0;
00580    int ret = -1;
00581    struct enum_search *s = NULL;
00582    int version = -1;
00583 
00584    strncat(naptrinput, number, sizeof(naptrinput) - 2);
00585 
00586    context.naptrinput = naptrinput;
00587    context.dst = dst;
00588    context.dstlen = dstlen;
00589    context.tech = tech;
00590    context.techlen = techlen;
00591    context.txt = txt;
00592    context.txtlen = txtlen;
00593 
00594    if (pos > 128)
00595       pos = 128;
00596    while (pos >= 0) {
00597       tmp[newpos++] = number[pos--];
00598       tmp[newpos++] = '.';
00599    }
00600 
00601    if (chan && ast_autoservice_start(chan) < 0)
00602       return -1;
00603 
00604    for (;;) {
00605       ast_mutex_lock(&enumlock);
00606       if (version != enumver) {
00607          /* Ooh, a reload... */
00608          s = toplevs;
00609          version = enumver;
00610       } else {
00611          s = s->next;
00612       }
00613       if (s) {
00614          ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos);
00615       }
00616       ast_mutex_unlock(&enumlock);
00617       if (!s)
00618          break;
00619 
00620       ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback);
00621       if (ret > 0)
00622          break;
00623    }
00624    if (ret < 0) {
00625       if (option_debug > 1)
00626          ast_log(LOG_DEBUG, "No such number found in ENUM: %s (%s)\n", tmp, strerror(errno));
00627       ret = 0;
00628    }
00629    if (chan)
00630       ret |= ast_autoservice_stop(chan);
00631    return ret;
00632 }


Generated on Sat Aug 6 00:39:55 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7