Mon Mar 20 08:25:45 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

srv.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * Funding provided by nic.at
00009  *
00010  * See http://www.asterisk.org for more information about
00011  * the Asterisk project. Please do not directly contact
00012  * any of the maintainers of this project for assistance;
00013  * the project provides a web site, mailing lists and IRC
00014  * channels for your use.
00015  *
00016  * This program is free software, distributed under the terms of
00017  * the GNU General Public License Version 2. See the LICENSE file
00018  * at the top of the source tree.
00019  */
00020 
00021 /*! \file
00022  *
00023  * \brief DNS SRV Record Lookup Support for Asterisk
00024  * 
00025  * \arg See also \ref AstENUM
00026  *
00027  */
00028 
00029 #include <sys/types.h>
00030 #include <netinet/in.h>
00031 #include <arpa/nameser.h>
00032 #if __APPLE_CC__ >= 1495
00033 #include <arpa/nameser_compat.h>
00034 #endif
00035 #include <resolv.h>
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <unistd.h>
00039 
00040 #include "asterisk.h"
00041 
00042 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00043 
00044 #include "asterisk/channel.h"
00045 #include "asterisk/logger.h"
00046 #include "asterisk/srv.h"
00047 #include "asterisk/dns.h"
00048 #include "asterisk/options.h"
00049 #include "asterisk/utils.h"
00050 
00051 #ifdef __APPLE__
00052 #undef T_SRV
00053 #define T_SRV 33
00054 #endif
00055 
00056 struct srv {
00057    unsigned short priority;
00058    unsigned short weight;
00059    unsigned short portnum;
00060 } __attribute__ ((__packed__));
00061 
00062 static int parse_srv(char *host, int hostlen, int *portno, char *answer, int len, char *msg)
00063 {
00064    int res = 0;
00065    struct srv *srv = (struct srv *)answer;
00066    char repl[256] = "";
00067 
00068    if (len < sizeof(struct srv)) {
00069       printf("Length too short\n");
00070       return -1;
00071    }
00072    answer += sizeof(struct srv);
00073    len -= sizeof(struct srv);
00074 
00075    if ((res = dn_expand((unsigned char *)msg, (unsigned char *)answer + len, (unsigned char *)answer, repl, sizeof(repl) - 1)) < 0) {
00076       ast_log(LOG_WARNING, "Failed to expand hostname\n");
00077       return -1;
00078    }
00079    if (res && strcmp(repl, ".")) {
00080       if (option_verbose > 3)
00081          ast_verbose( VERBOSE_PREFIX_3 "parse_srv: SRV mapped to host %s, port %d\n", repl, ntohs(srv->portnum));
00082       if (host) {
00083          ast_copy_string(host, repl, hostlen);
00084          host[hostlen-1] = '\0';
00085       }
00086       if (portno)
00087          *portno = ntohs(srv->portnum);
00088       return 0;
00089    }
00090    return -1;
00091 }
00092 
00093 struct srv_context {
00094    char *host;
00095    int hostlen;
00096    int *port;
00097 };
00098 
00099 static int srv_callback(void *context, char *answer, int len, char *fullanswer)
00100 {
00101    struct srv_context *c = (struct srv_context *)context;
00102 
00103    if (parse_srv(c->host, c->hostlen, c->port, answer, len, fullanswer)) {
00104       ast_log(LOG_WARNING, "Failed to parse srv\n");
00105       return -1;
00106    }
00107 
00108    if (!ast_strlen_zero(c->host))
00109       return 1;
00110 
00111    return 0;
00112 }
00113 
00114 int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
00115 {
00116    struct srv_context context;
00117    int ret;
00118 
00119    context.host = host;
00120    context.hostlen = hostlen;
00121    context.port = port;
00122 
00123    if (chan && ast_autoservice_start(chan) < 0)
00124       return -1;
00125 
00126    ret = ast_search_dns(&context, service, C_IN, T_SRV, srv_callback);
00127 
00128    if (chan)
00129       ret |= ast_autoservice_stop(chan);
00130 
00131    if (ret <= 0) {
00132       host[0] = '\0';
00133       *port = -1;
00134       return ret;
00135    }
00136    return ret;
00137 }

Generated on Mon Mar 20 08:25:45 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1