Wed Oct 28 11:46:08 2009

Asterisk developer's documentation


enum.h File Reference

DNS and ENUM functions. More...

#include "asterisk/channel.h"

Include dependency graph for enum.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  enum_context
struct  enum_naptr_rr
struct  naptr

Functions

int ast_enum_init (void)
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, struct enum_context **argcontext)
 Lookup entry in ENUM.
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   ) 

Definition at line 667 of file enum.c.

References private_enum_init().

Referenced by main().

00668 {
00669    return private_enum_init(0);
00670 }

int ast_enum_reload ( void   ) 

Definition at line 672 of file enum.c.

References private_enum_init().

00673 {
00674    return private_enum_init(1);
00675 }

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,
struct enum_context **  argcontext 
)

Lookup entry in ENUM.

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
argcontext Argument for caching results into an enum_context pointer (NULL is used for not caching)
Return values:
1 if found
0 if not found
-1 on hangup

Definition at line 380 of file enum.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_calloc, ast_copy_string(), ast_debug, ast_free, ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), context, enum_context::dst, enum_context::dstlen, enum_callback(), enumlock, ENUMLOOKUP_OPTIONS_COUNT, errno, enum_naptr_rr::naptr, enum_context::naptr_rrs, enum_context::naptr_rrs_count, enum_context::naptrinput, enum_search::next, enum_context::options, naptr::order, enum_context::position, naptr::pref, enum_naptr_rr::result, s, enum_naptr_rr::sort_pos, enum_naptr_rr::tech, enum_context::tech, enum_context::techlen, enum_search::toplev, toplevs, and version.

Referenced by enum_query_read(), and function_enum().

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

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 550 of file enum.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_search_dns(), enum_context::dst, enum_context::dstlen, enumlock, errno, enum_context::naptrinput, enum_search::next, s, enum_context::tech, enum_context::techlen, enum_search::toplev, toplevs, enum_context::txt, txt_callback(), enum_context::txtlen, and version.

Referenced by function_txtcidname().

00551 {
00552    struct enum_context context;
00553    char tmp[259 + 512];
00554    char naptrinput[512] = "+";
00555    int pos = strlen(number) - 1;
00556    int newpos = 0;
00557    int ret = -1;
00558    struct enum_search *s = NULL;
00559    int version = -1;
00560 
00561    strncat(naptrinput, number, sizeof(naptrinput) - 2);
00562 
00563    context.naptrinput = naptrinput;
00564    context.dst = dst;
00565    context.dstlen = dstlen;
00566    context.tech = tech;
00567    context.techlen = techlen;
00568    context.txt = txt;
00569    context.txtlen = txtlen;
00570 
00571    if (pos > 128)
00572       pos = 128;
00573    while (pos >= 0) {
00574       tmp[newpos++] = number[pos--];
00575       tmp[newpos++] = '.';
00576    }
00577 
00578    if (chan && ast_autoservice_start(chan) < 0)
00579       return -1;
00580 
00581    for (;;) {
00582       ast_mutex_lock(&enumlock);
00583       if (version != enumver) {
00584          /* Ooh, a reload... */
00585          s = toplevs;
00586          version = enumver;
00587       } else {
00588          s = s->next;
00589       }
00590       if (s) {
00591          ast_copy_string(tmp + newpos, s->toplev, sizeof(tmp) - newpos);
00592       }
00593       ast_mutex_unlock(&enumlock);
00594       if (!s)
00595          break;
00596 
00597       ret = ast_search_dns(&context, tmp, C_IN, T_TXT, txt_callback);
00598       if (ret > 0)
00599          break;
00600    }
00601    if (ret < 0) {
00602       ast_debug(2, "No such number found in ENUM: %s (%s)\n", tmp, strerror(errno));
00603       ret = 0;
00604    }
00605    if (chan)
00606       ret |= ast_autoservice_stop(chan);
00607    return ret;
00608 }


Generated on Wed Oct 28 11:46:08 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6