diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-01-19 00:28:49 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-01-19 00:28:49 +0000 |
commit | fb0c85edeb22827b7f7a242fb5266c1944b40c9e (patch) | |
tree | 1fa70043dacf63a29de615f9f6c82ad0f824f011 /main/srv.c | |
parent | 4c5831b3e5f9c280dafe6ec76c4f067d8ebcc713 (diff) |
Create iterative method for querying SRV results, and use that for finding AGI servers.
(closes issue #14775)
Reported by: _brent_
Patches:
20091215__issue14775.diff.txt uploaded by tilghman (license 14)
hagi-5.patch uploaded by brent (license 388)
Tested by: _brent_
Reviewboard: https://reviewboard.asterisk.org/r/378/
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@241188 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/srv.c')
-rw-r--r-- | main/srv.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/main/srv.c b/main/srv.c index 081994249..3be8bbd00 100644 --- a/main/srv.c +++ b/main/srv.c @@ -64,6 +64,7 @@ struct srv_entry { struct srv_context { unsigned int have_weights:1; + struct srv_entry *prev; AST_LIST_HEAD_NOLOCK(srv_entries, srv_entry) entries; }; @@ -197,6 +198,55 @@ static void process_weights(struct srv_context *context) AST_LIST_APPEND_LIST(&context->entries, &newlist, list); } +int ast_srv_lookup(struct srv_context **context, const char *service, const char **host, unsigned short *port) +{ + struct srv_entry *cur; + + if (*context == NULL) { + if (!(*context = ast_calloc(1, sizeof(struct srv_context)))) { + return -1; + } + AST_LIST_HEAD_INIT_NOLOCK(&(*context)->entries); + + if ((ast_search_dns(*context, service, C_IN, T_SRV, srv_callback)) < 0) { + ast_free(*context); + *context = NULL; + return -1; + } + + if ((*context)->have_weights) { + process_weights(*context); + } + + (*context)->prev = AST_LIST_FIRST(&(*context)->entries); + *host = (*context)->prev->host; + *port = (*context)->prev->port; + return 0; + } + + if (((*context)->prev = AST_LIST_NEXT((*context)->prev, list))) { + /* Retrieve next item in result */ + *host = (*context)->prev->host; + *port = (*context)->prev->port; + return 0; + } else { + /* No more results */ + while ((cur = AST_LIST_REMOVE_HEAD(&(*context)->entries, list))) { + ast_free(cur); + } + ast_free(*context); + *context = NULL; + return 1; + } +} + +void ast_srv_cleanup(struct srv_context **context) +{ + const char *host; + unsigned short port; + while (!(ast_srv_lookup(context, NULL, &host, &port))); +} + int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service) { struct srv_context context = { .entries = AST_LIST_HEAD_NOLOCK_INIT_VALUE }; |