Asterisk - The Open Source Telephony Project  18.5.0
Functions
srv.h File Reference

Support for DNS SRV records, used in to locate SIP services. More...

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

Go to the source code of this file.

Functions

int ast_get_srv (struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
 Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup. More...
 
void ast_srv_cleanup (struct srv_context **context)
 Cleanup resources associated with ast_srv_lookup. More...
 
int ast_srv_get_nth_record (struct srv_context *context, int record_num, const char **host, unsigned short *port, unsigned short *priority, unsigned short *weight)
 Retrieve details from a specific SRV record. More...
 
unsigned int ast_srv_get_record_count (struct srv_context *context)
 Get the number of records for a given SRV context. More...
 
int ast_srv_lookup (struct srv_context **context, const char *service, const char **host, unsigned short *port)
 Retrieve set of SRV lookups, in order. More...
 

Detailed Description

Support for DNS SRV records, used in to locate SIP services.

Note
Note: This SRV record support will respect the priority and weight elements of the records that are returned, but there are no provisions for retrying or failover between records.

Definition in file srv.h.

Function Documentation

◆ ast_get_srv()

int ast_get_srv ( struct ast_channel chan,
char *  host,
int  hostlen,
int *  port,
const char *  service 
)

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

Only do SRV record lookup if you get a domain without a port. If you get a port #, it's a DNS host name.

Parameters
chanAst channel
hosthost name (return value)
hostlenLength of string "host"
portPort number (return value)
serviceService tag for SRV lookup (like "_sip._udp" or "_stun._udp"

Definition at line 260 of file srv.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_debug, ast_free, AST_LIST_HEAD_NOLOCK_INIT_VALUE, AST_LIST_REMOVE_HEAD, ast_search_dns(), srv_context::entries, srv_context::have_weights, srv_entry::host, srv_entry::list, srv_entry::port, process_weights(), and srv_callback().

Referenced by ast_get_ip_or_srv(), and create_addr().

261 {
262  struct srv_context context = { .entries = AST_LIST_HEAD_NOLOCK_INIT_VALUE };
263  struct srv_entry *current;
264  int ret;
265 
266  if (chan && ast_autoservice_start(chan) < 0) {
267  return -1;
268  }
269 
270  ret = ast_search_dns(&context, service, C_IN, T_SRV, srv_callback);
271 
272  if (context.have_weights) {
273  process_weights(&context);
274  }
275 
276  if (chan) {
277  ret |= ast_autoservice_stop(chan);
278  }
279 
280  /* TODO: there could be a "." entry in the returned list of
281  answers... if so, this requires special handling */
282 
283  /* the list of entries will be sorted in the proper selection order
284  already, so we just need the first one (if any) */
285 
286  if ((ret > 0) && (current = AST_LIST_REMOVE_HEAD(&context.entries, list))) {
287  ast_copy_string(host, current->host, hostlen);
288  *port = current->port;
289  ast_free(current);
290  ast_debug(4, "ast_get_srv: SRV lookup for '%s' mapped to host %s, port %d\n",
291  service, host, *port);
292  } else {
293  host[0] = '\0';
294  *port = -1;
295  }
296 
297  while ((current = AST_LIST_REMOVE_HEAD(&context.entries, list))) {
298  ast_free(current);
299  }
300 
301  return ret;
302 }
unsigned int have_weights
Definition: srv.c:66
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
char host[1]
Definition: srv.c:62
static void process_weights(struct srv_context *context)
Definition: srv.c:150
int ast_search_dns(void *context, const char *dname, int class, int type, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
Perform DNS lookup (used by DNS, enum and SRV lookups)
Definition: dns.c:493
enum ast_cc_service_type service
Definition: chan_sip.c:949
unsigned short port
Definition: srv.c:59
struct srv_context::srv_entries entries
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct srv_entry::@420 list
static char host[256]
Definition: muted.c:77
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
Definition: srv.c:56
#define ast_free(a)
Definition: astmm.h:182
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:251
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static int srv_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Definition: srv.c:113

◆ ast_srv_cleanup()

void ast_srv_cleanup ( struct srv_context **  context)

Cleanup resources associated with ast_srv_lookup.

Parameters
contextPointer passed into ast_srv_lookup

Definition at line 248 of file srv.c.

References ast_srv_lookup(), srv_entry::host, NULL, and srv_entry::port.

Referenced by ip_identify_match_srv_lookup(), launch_ha_netscript(), srds_destroy_cb(), and srv_datastore_setup().

249 {
250  const char *host;
251  unsigned short port;
252 
253  if (*context) {
254  /* We have a context to clean up. */
255  while (!(ast_srv_lookup(context, NULL, &host, &port))) {
256  }
257  }
258 }
#define NULL
Definition: resample.c:96
unsigned short port
Definition: srv.c:59
static char host[256]
Definition: muted.c:77
int ast_srv_lookup(struct srv_context **context, const char *service, const char **host, unsigned short *port)
Retrieve set of SRV lookups, in order.
Definition: srv.c:202

◆ ast_srv_get_nth_record()

int ast_srv_get_nth_record ( struct srv_context context,
int  record_num,
const char **  host,
unsigned short *  port,
unsigned short *  priority,
unsigned short *  weight 
)

Retrieve details from a specific SRV record.

After calling ast_srv_lookup, the srv_context will contain the data from several records. You can retrieve the data of a specific one by asking for a specific record number. The records are sorted based on priority and secondarily based on weight. See RFC 2782 for the exact sorting rules.

Parameters
contextThe context returned by ast_srv_lookup
record_numThe 1-indexed record number to retrieve
[out]hostThe host portion of the record
[out]portThe port portion of the record
[out]priorityThe priority portion of the record
[out]weightThe weight portion of the record
Return values
-1Failed to retrieve information. Likely due to an out of range record_num
0Success

Definition at line 309 of file srv.c.

References AST_LIST_TRAVERSE, srv_context::entries, srv_entry::host, srv_entry::list, srv_context::num_records, srv_entry::port, srv_entry::priority, and srv_entry::weight.

Referenced by srv_result_read().

311 {
312  int i = 1;
313  int res = -1;
314  struct srv_entry *entry;
315 
316  if (record_num < 1 || record_num > context->num_records) {
317  return res;
318  }
319 
320  AST_LIST_TRAVERSE(&context->entries, entry, list) {
321  if (i == record_num) {
322  *host = entry->host;
323  *port = entry->port;
324  *priority = entry->priority;
325  *weight = entry->weight;
326  res = 0;
327  break;
328  }
329  ++i;
330  }
331 
332  return res;
333 }
char host[1]
Definition: srv.c:62
static int priority
unsigned short port
Definition: srv.c:59
struct srv_context::srv_entries entries
struct srv_entry::@420 list
static char host[256]
Definition: muted.c:77
char weight
unsigned short priority
Definition: srv.c:57
unsigned int num_records
Definition: srv.c:68
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: srv.c:56
Definition: search.h:40
unsigned short weight
Definition: srv.c:58

◆ ast_srv_get_record_count()

unsigned int ast_srv_get_record_count ( struct srv_context context)

Get the number of records for a given SRV context.

This is meant to be used after calling ast_srv_lookup, so that one may retrieve the number of records returned during a specific SRV lookup.

Parameters
contextThe context returned by ast_srv_lookup
Returns
Number of records in context

Definition at line 304 of file srv.c.

References srv_context::num_records.

Referenced by srv_result_read().

305 {
306  return context->num_records;
307 }
unsigned int num_records
Definition: srv.c:68

◆ ast_srv_lookup()

int ast_srv_lookup ( struct srv_context **  context,
const char *  service,
const char **  host,
unsigned short *  port 
)

Retrieve set of SRV lookups, in order.

Parameters
[in]contextA pointer in which to hold the result
[in]serviceThe service name to look up
[out]hostResult host
[out]portAssociated TCP portnum
Return values
-1Query failed
0Result exists in host and port
1No more results

Definition at line 202 of file srv.c.

References ast_calloc, ast_free, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_search_dns(), srv_entry::list, NULL, process_weights(), and srv_callback().

Referenced by ast_srv_cleanup(), ip_identify_match_srv_lookup(), launch_ha_netscript(), and srv_datastore_setup().

203 {
204  struct srv_entry *cur;
205 
206  if (*context == NULL) {
207  if (!(*context = ast_calloc(1, sizeof(struct srv_context)))) {
208  return -1;
209  }
210  AST_LIST_HEAD_INIT_NOLOCK(&(*context)->entries);
211 
212  if (((ast_search_dns(*context, service, C_IN, T_SRV, srv_callback)) < 1) ||
213  AST_LIST_EMPTY(&(*context)->entries)) {
214  ast_free(*context);
215  *context = NULL;
216  return -1;
217  }
218 
219  if ((*context)->have_weights) {
220  process_weights(*context);
221  }
222 
223  (*context)->prev = AST_LIST_FIRST(&(*context)->entries);
224  *host = (*context)->prev->host;
225  *port = (*context)->prev->port;
226  AST_LIST_TRAVERSE(&(*context)->entries, cur, list) {
227  ++((*context)->num_records);
228  }
229  return 0;
230  }
231 
232  if (((*context)->prev = AST_LIST_NEXT((*context)->prev, list))) {
233  /* Retrieve next item in result */
234  *host = (*context)->prev->host;
235  *port = (*context)->prev->port;
236  return 0;
237  } else {
238  /* No more results */
239  while ((cur = AST_LIST_REMOVE_HEAD(&(*context)->entries, list))) {
240  ast_free(cur);
241  }
242  ast_free(*context);
243  *context = NULL;
244  return 1;
245  }
246 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
static void process_weights(struct srv_context *context)
Definition: srv.c:150
int ast_search_dns(void *context, const char *dname, int class, int type, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
Perform DNS lookup (used by DNS, enum and SRV lookups)
Definition: dns.c:493
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
enum ast_cc_service_type service
Definition: chan_sip.c:949
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
unsigned short port
Definition: srv.c:59
struct srv_entry::@420 list
static char host[256]
Definition: muted.c:77
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: srv.c:56
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
static int srv_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
Definition: srv.c:113