dns_recurring.c File Reference

DNS Recurring Query Support. More...

#include "asterisk.h"
#include "asterisk/astobj2.h"
#include "asterisk/linkedlists.h"
#include "asterisk/sched.h"
#include "asterisk/strings.h"
#include "asterisk/dns_core.h"
#include "asterisk/dns_recurring.h"
#include "asterisk/dns_internal.h"
#include <arpa/nameser.h>

Include dependency graph for dns_recurring.c:

Go to the source code of this file.

Functions

struct ast_dns_query_recurringast_dns_resolve_recurring (const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
 Asynchronously resolve a DNS query, and continue resolving it according to the lowest TTL available.
int ast_dns_resolve_recurring_cancel (struct ast_dns_query_recurring *recurring)
 Cancel an asynchronous recurring DNS resolution.
static void dns_query_recurring_destroy (void *data)
 Destructor for a DNS query.
static void dns_query_recurring_resolution_callback (const struct ast_dns_query *query)
 Query resolution callback.
static int dns_query_recurring_scheduled_callback (const void *data)
 Scheduled recurring query callback.


Detailed Description

DNS Recurring Query Support.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file dns_recurring.c.


Function Documentation

struct ast_dns_query_recurring* ast_dns_resolve_recurring ( const char *  name,
int  rr_type,
int  rr_class,
ast_dns_resolve_callback  callback,
void *  data 
) [read]

Asynchronously resolve a DNS query, and continue resolving it according to the lowest TTL available.

Parameters:
name The name of what to resolve
rr_type Resource record type
rr_class Resource record class
callback The callback to invoke upon completion
data User data to make available on the query
Return values:
non-NULL success - query has been sent for resolution
NULL failure
Note:
The user data passed in to this function must be ao2 allocated

This query will continue to happen according to the lowest TTL unless cancelled using ast_dns_resolve_recurring_cancel

It is NOT possible for the callback to be invoked concurrently for the query multiple times

The query will occur when the TTL expires, not before. This means that there is a period of time where the previous information can be considered stale.

If the TTL is determined to be 0 (the record specifies 0, or no records exist) this will cease doing a recurring query. It is the responsibility of the caller to resume querying at an interval they determine.

Definition at line 103 of file dns_recurring.c.

References ast_dns_query_recurring::active, ao2_alloc, ao2_bump, ao2_ref, ast_dns_get_sched(), ast_dns_resolve_async(), ast_strlen_zero, ast_dns_query_recurring::callback, dns_query_recurring_destroy(), dns_query_recurring_resolution_callback(), ast_dns_query_recurring::name, NULL, ast_dns_query_recurring::rr_class, ast_dns_query_recurring::rr_type, ast_dns_query_recurring::timer, and ast_dns_query_recurring::user_data.

Referenced by AST_TEST_DEFINE().

00104 {
00105    struct ast_dns_query_recurring *recurring;
00106 
00107    if (ast_strlen_zero(name) || !callback || !ast_dns_get_sched()) {
00108       return NULL;
00109    }
00110 
00111    recurring = ao2_alloc(sizeof(*recurring) + strlen(name) + 1, dns_query_recurring_destroy);
00112    if (!recurring) {
00113       return NULL;
00114    }
00115 
00116    recurring->callback = callback;
00117    recurring->user_data = ao2_bump(data);
00118    recurring->timer = -1;
00119    recurring->rr_type = rr_type;
00120    recurring->rr_class = rr_class;
00121    strcpy(recurring->name, name); /* SAFE */
00122 
00123    recurring->active = ast_dns_resolve_async(name, rr_type, rr_class, dns_query_recurring_resolution_callback, recurring);
00124    if (!recurring->active) {
00125       ao2_ref(recurring, -1);
00126       return NULL;
00127    }
00128 
00129    return recurring;
00130 }

int ast_dns_resolve_recurring_cancel ( struct ast_dns_query_recurring recurring  ) 

Cancel an asynchronous recurring DNS resolution.

Parameters:
query The DNS query returned from ast_dns_resolve_recurring
Return values:
0 success - any active query has been cancelled and the query will no longer occur
-1 failure - an active query was in progress and could not be cancelled
Note:
If successfully cancelled the callback will not be invoked

This function does NOT drop your reference to the recurring query, this should be dropped using ao2_ref

Definition at line 132 of file dns_recurring.c.

References ast_dns_query_recurring::active, ao2_lock, ao2_ref, ao2_replace, ao2_unlock, ast_dns_get_sched(), ast_dns_resolve_cancel(), AST_SCHED_DEL_UNREF, ast_dns_query_recurring::cancelled, NULL, and ast_dns_query_recurring::timer.

Referenced by AST_TEST_DEFINE().

00133 {
00134    int res = 0;
00135 
00136    ao2_lock(recurring);
00137 
00138    recurring->cancelled = 1;
00139    AST_SCHED_DEL_UNREF(ast_dns_get_sched(), recurring->timer, ao2_ref(recurring, -1));
00140 
00141    if (recurring->active) {
00142       res = ast_dns_resolve_cancel(recurring->active);
00143       ao2_replace(recurring->active, NULL);
00144    }
00145 
00146    ao2_unlock(recurring);
00147 
00148    return res;
00149 }

static void dns_query_recurring_destroy ( void *  data  )  [static]

Destructor for a DNS query.

Definition at line 45 of file dns_recurring.c.

References ao2_cleanup, and ast_dns_query_recurring::user_data.

Referenced by ast_dns_resolve_recurring().

00046 {
00047    struct ast_dns_query_recurring *recurring = data;
00048 
00049    ao2_cleanup(recurring->user_data);
00050 }

static void dns_query_recurring_resolution_callback ( const struct ast_dns_query query  )  [static]

Query resolution callback.

Definition at line 73 of file dns_recurring.c.

References ast_dns_query_recurring::active, ao2_bump, ao2_lock, ao2_ref, ao2_replace, ao2_unlock, ast_dns_get_sched(), ast_dns_query_get_data(), ast_dns_query_get_result(), ast_dns_result_get_lowest_ttl(), ast_sched_add(), ast_dns_query_recurring::callback, ast_dns_query_recurring::cancelled, dns_query_recurring_scheduled_callback(), MIN, NULL, result, ast_dns_query_recurring::timer, and ast_dns_query_recurring::user_data.

Referenced by ast_dns_resolve_recurring(), and dns_query_recurring_scheduled_callback().

00074 {
00075    struct ast_dns_query_recurring *recurring = ast_dns_query_get_data(query);
00076 
00077    /* Replace the user data so the actual callback sees what it provided */
00078    ((struct ast_dns_query*)query)->user_data = ao2_bump(recurring->user_data);
00079    recurring->callback(query);
00080 
00081    ao2_lock(recurring);
00082    /* So.. if something has not externally cancelled this we can reschedule based on the TTL */
00083    if (!recurring->cancelled) {
00084       const struct ast_dns_result *result = ast_dns_query_get_result(query);
00085       int ttl = MIN(ast_dns_result_get_lowest_ttl(result), INT_MAX / 1000);
00086 
00087       if (ttl) {
00088          recurring->timer = ast_sched_add(ast_dns_get_sched(), ttl * 1000, dns_query_recurring_scheduled_callback, ao2_bump(recurring));
00089          if (recurring->timer < 0) {
00090             /* It is impossible for this to be the last reference as this callback function holds a reference itself */
00091             ao2_ref(recurring, -1);
00092          }
00093       }
00094    }
00095 
00096    ao2_replace(recurring->active, NULL);
00097    ao2_unlock(recurring);
00098 
00099    /* Since we stole the reference from the query we need to drop it ourselves */
00100    ao2_ref(recurring, -1);
00101 }

static int dns_query_recurring_scheduled_callback ( const void *  data  )  [static]

Scheduled recurring query callback.

Definition at line 55 of file dns_recurring.c.

References ast_dns_query_recurring::active, ao2_lock, ao2_ref, ao2_unlock, ast_dns_resolve_async(), ast_dns_query_recurring::cancelled, dns_query_recurring_resolution_callback(), ast_dns_query_recurring::name, ast_dns_query_recurring::rr_class, ast_dns_query_recurring::rr_type, and ast_dns_query_recurring::timer.

Referenced by dns_query_recurring_resolution_callback().

00056 {
00057    struct ast_dns_query_recurring *recurring = (struct ast_dns_query_recurring *)data;
00058 
00059    ao2_lock(recurring);
00060    recurring->timer = -1;
00061    if (!recurring->cancelled) {
00062       recurring->active = ast_dns_resolve_async(recurring->name, recurring->rr_type, recurring->rr_class, dns_query_recurring_resolution_callback,
00063          recurring);
00064    }
00065    ao2_unlock(recurring);
00066 
00067    ao2_ref(recurring, -1);
00068 
00069    return 0;
00070 }


Generated on Thu Apr 16 06:30:43 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6