![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
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 * \author Mark Spencer <markster@digium.com> 00026 * 00027 * \arg See also \ref AstENUM 00028 * 00029 * \note Funding provided by nic.at 00030 */ 00031 00032 #include "asterisk.h" 00033 00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 40722 $") 00035 00036 #include <sys/types.h> 00037 #include <netinet/in.h> 00038 #include <arpa/nameser.h> 00039 #if __APPLE_CC__ >= 1495 00040 #include <arpa/nameser_compat.h> 00041 #endif 00042 #include <resolv.h> 00043 #include <stdio.h> 00044 #include <string.h> 00045 #include <unistd.h> 00046 00047 #include "asterisk/channel.h" 00048 #include "asterisk/logger.h" 00049 #include "asterisk/srv.h" 00050 #include "asterisk/dns.h" 00051 #include "asterisk/options.h" 00052 #include "asterisk/utils.h" 00053 00054 #ifdef __APPLE__ 00055 #undef T_SRV 00056 #define T_SRV 33 00057 #endif 00058 00059 struct srv { 00060 unsigned short priority; 00061 unsigned short weight; 00062 unsigned short portnum; 00063 } __attribute__ ((__packed__)); 00064 00065 static int parse_srv(char *host, int hostlen, int *portno, unsigned char *answer, int len, unsigned char *msg) 00066 { 00067 int res = 0; 00068 struct srv *srv = (struct srv *)answer; 00069 char repl[256] = ""; 00070 00071 if (len < sizeof(struct srv)) { 00072 printf("Length too short\n"); 00073 return -1; 00074 } 00075 answer += sizeof(struct srv); 00076 len -= sizeof(struct srv); 00077 00078 if ((res = dn_expand(msg, answer + len, answer, repl, sizeof(repl) - 1)) < 0) { 00079 ast_log(LOG_WARNING, "Failed to expand hostname\n"); 00080 return -1; 00081 } 00082 if (res && strcmp(repl, ".")) { 00083 if (option_verbose > 3) 00084 ast_verbose( VERBOSE_PREFIX_3 "parse_srv: SRV mapped to host %s, port %d\n", repl, ntohs(srv->portnum)); 00085 if (host) { 00086 ast_copy_string(host, repl, hostlen); 00087 host[hostlen-1] = '\0'; 00088 } 00089 if (portno) 00090 *portno = ntohs(srv->portnum); 00091 return 0; 00092 } 00093 return -1; 00094 } 00095 00096 struct srv_context { 00097 char *host; 00098 int hostlen; 00099 int *port; 00100 }; 00101 00102 static int srv_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer) 00103 { 00104 struct srv_context *c = (struct srv_context *)context; 00105 00106 if (parse_srv(c->host, c->hostlen, c->port, answer, len, fullanswer)) { 00107 ast_log(LOG_WARNING, "Failed to parse srv\n"); 00108 return -1; 00109 } 00110 00111 if (!ast_strlen_zero(c->host)) 00112 return 1; 00113 00114 return 0; 00115 } 00116 00117 int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service) 00118 { 00119 struct srv_context context; 00120 int ret; 00121 00122 context.host = host; 00123 context.hostlen = hostlen; 00124 context.port = port; 00125 00126 if (chan && ast_autoservice_start(chan) < 0) 00127 return -1; 00128 00129 ret = ast_search_dns(&context, service, C_IN, T_SRV, srv_callback); 00130 00131 if (chan) 00132 ret |= ast_autoservice_stop(chan); 00133 00134 if (ret <= 0) { 00135 host[0] = '\0'; 00136 *port = -1; 00137 return ret; 00138 } 00139 return ret; 00140 }