aboutsummaryrefslogtreecommitdiffstats
path: root/main/srv.c
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2010-01-19 00:28:49 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2010-01-19 00:28:49 +0000
commitfb0c85edeb22827b7f7a242fb5266c1944b40c9e (patch)
tree1fa70043dacf63a29de615f9f6c82ad0f824f011 /main/srv.c
parent4c5831b3e5f9c280dafe6ec76c4f067d8ebcc713 (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.c50
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 };