Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Macros | Functions
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.


#define EXTRA_TTL   2
 Delay between TTL expiration and the next DNS query, to make sure the resolver cache really expired. More...
#define MAX_TTL   ((INT_MAX - EXTRA_TTL) / 1000)


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. More...
int ast_dns_resolve_recurring_cancel (struct ast_dns_query_recurring *recurring)
 Cancel an asynchronous recurring DNS resolution. More...
static void dns_query_recurring_destroy (void *data)
 Destructor for a DNS query. More...
static void dns_query_recurring_resolution_callback (const struct ast_dns_query *query)
 Query resolution callback. More...
static int dns_query_recurring_scheduled_callback (const void *data)
 Scheduled recurring query callback. More...

Detailed Description

DNS Recurring Query Support.

Joshua Colp

Definition in file dns_recurring.c.

Macro Definition Documentation


#define EXTRA_TTL   2

Delay between TTL expiration and the next DNS query, to make sure the resolver cache really expired.

Definition at line 44 of file dns_recurring.c.


#define MAX_TTL   ((INT_MAX - EXTRA_TTL) / 1000)

Definition at line 45 of file dns_recurring.c.

Function Documentation

◆ ast_dns_resolve_recurring()

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 

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

nameThe name of what to resolve
rr_typeResource record type
rr_classResource record class
callbackThe callback to invoke upon completion
dataUser data to make available on the query
Return values
non-NULLsuccess - query has been sent for resolution
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 114 of file dns_recurring.c.

115 {
116  struct ast_dns_query_recurring *recurring;
119  return NULL;
120  }
122  recurring = ao2_alloc(sizeof(*recurring) + strlen(name) + 1, dns_query_recurring_destroy);
123  if (!recurring) {
124  return NULL;
125  }
127  recurring->callback = callback;
128  recurring->user_data = ao2_bump(data);
129  recurring->timer = -1;
130  recurring->rr_type = rr_type;
131  recurring->rr_class = rr_class;
132  strcpy(recurring->name, name); /* SAFE */
135  if (!recurring->active) {
136  ao2_ref(recurring, -1);
137  return NULL;
138  }
140  return recurring;
141 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
struct ast_dns_query_active * ast_dns_resolve_async(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
Asynchronously resolve a DNS query.
Definition: dns_core.c:247
struct ast_sched_context * ast_dns_get_sched(void)
Retrieve the DNS scheduler context.
Definition: dns_core.c:52
static void dns_query_recurring_destroy(void *data)
Destructor for a DNS query.
Definition: dns_recurring.c:48
static void dns_query_recurring_resolution_callback(const struct ast_dns_query *query)
Query resolution callback.
Definition: dns_recurring.c:76
static const char name[]
Definition: format_mp3.c:68
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
A recurring DNS query.
Definition: dns_internal.h:157
void * user_data
User-specific data.
Definition: dns_internal.h:161
ast_dns_resolve_callback callback
Callback to invoke upon completion.
Definition: dns_internal.h:159
struct ast_dns_query_active * active
Current active query.
Definition: dns_internal.h:163
int rr_class
Resource record class.
Definition: dns_internal.h:171
int rr_type
Resource record type.
Definition: dns_internal.h:169
int timer
Scheduled timer for next resolution.
Definition: dns_internal.h:167
char name[0]
The name of what is being resolved.
Definition: dns_internal.h:173

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, 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(), and rtp_reload().

◆ ast_dns_resolve_recurring_cancel()

int ast_dns_resolve_recurring_cancel ( struct ast_dns_query_recurring recurring)

Cancel an asynchronous recurring DNS resolution.

recurringThe DNS query returned from ast_dns_resolve_recurring
Return values
0success - any active query has been cancelled and the query will no longer occur
-1failure - an active query was in progress and could not be cancelled
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 143 of file dns_recurring.c.

144 {
145  int res = 0;
147  ao2_lock(recurring);
149  recurring->cancelled = 1;
150  AST_SCHED_DEL_UNREF(ast_dns_get_sched(), recurring->timer, ao2_ref(recurring, -1));
152  if (recurring->active) {
153  res = ast_dns_resolve_cancel(recurring->active);
154  ao2_replace(recurring->active, NULL);
155  }
157  ao2_unlock(recurring);
159  return res;
160 }
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define ao2_lock(a)
Definition: astobj2.h:717
int ast_dns_resolve_cancel(struct ast_dns_query_active *active)
Cancel an asynchronous DNS resolution.
Definition: dns_core.c:272
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:82
unsigned int cancelled
The recurring query has been cancelled.
Definition: dns_internal.h:165

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().

◆ dns_query_recurring_destroy()

static void dns_query_recurring_destroy ( void *  data)

Destructor for a DNS query.

Definition at line 48 of file dns_recurring.c.

49 {
50  struct ast_dns_query_recurring *recurring = data;
52  ao2_cleanup(recurring->user_data);
53 }
#define ao2_cleanup(obj)
Definition: astobj2.h:1934

References ao2_cleanup, and ast_dns_query_recurring::user_data.

Referenced by ast_dns_resolve_recurring().

◆ dns_query_recurring_resolution_callback()

static void dns_query_recurring_resolution_callback ( const struct ast_dns_query query)

Query resolution callback.

Definition at line 76 of file dns_recurring.c.

77 {
78  struct ast_dns_query_recurring *recurring = ast_dns_query_get_data(query);
79  struct ast_dns_query *callback_query;
81  /* Create a separate query to invoke the user specific callback on as the
82  * recurring query user data may get used externally (by the unit test)
83  * and thus changing it is problematic
84  */
85  callback_query = dns_query_alloc(query->name, query->rr_type, query->rr_class,
86  recurring->callback, recurring->user_data);
87  if (callback_query) {
88  /* The result is immutable at this point and can be safely provided */
89  callback_query->result = query->result;
90  callback_query->callback(callback_query);
91  callback_query->result = NULL;
92  ao2_ref(callback_query, -1);
93  }
95  ao2_lock(recurring);
96  /* So.. if something has not externally cancelled this we can reschedule based on the TTL */
97  if (!recurring->cancelled) {
98  const struct ast_dns_result *result = ast_dns_query_get_result(query);
101  if (ttl) {
103  if (recurring->timer < 0) {
104  /* It is impossible for this to be the last reference as the query has a reference to it */
105  ao2_ref(recurring, -1);
106  }
107  }
108  }
110  ao2_replace(recurring->active, NULL);
111  ao2_unlock(recurring);
112 }
static PGresult * result
Definition: cel_pgsql.c:84
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
void * ast_dns_query_get_data(const struct ast_dns_query *query)
Get the user specific data of a DNS query.
Definition: dns_core.c:72
int ast_dns_result_get_lowest_ttl(const struct ast_dns_result *result)
Retrieve the lowest TTL from a result.
Definition: dns_core.c:112
struct ast_dns_query * dns_query_alloc(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
Allocate a DNS query (but do not start resolution)
Definition: dns_core.c:193
#define EXTRA_TTL
Delay between TTL expiration and the next DNS query, to make sure the resolver cache really expired.
Definition: dns_recurring.c:44
#define MAX_TTL
Definition: dns_recurring.c:45
static int dns_query_recurring_scheduled_callback(const void *data)
Scheduled recurring query callback.
Definition: dns_recurring.c:58
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:567
A DNS query.
Definition: dns_internal.h:137
ast_dns_resolve_callback callback
Callback to invoke upon completion.
Definition: dns_internal.h:139
struct ast_dns_result * result
Result of the DNS query.
Definition: dns_internal.h:147
int rr_class
Resource record class.
Definition: dns_internal.h:151
int rr_type
Resource record type.
Definition: dns_internal.h:149
char name[0]
The name of what is being resolved.
Definition: dns_internal.h:153
The result of a DNS query.
Definition: dns_internal.h:117
#define MIN(a, b)
Definition: utils.h:226

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::callback, ast_dns_query_recurring::callback, ast_dns_query_recurring::cancelled, dns_query_alloc(), dns_query_recurring_scheduled_callback(), EXTRA_TTL, MAX_TTL, MIN, ast_dns_query::name, NULL, result, ast_dns_query::result, ast_dns_query::rr_class, ast_dns_query::rr_type, ast_dns_query_recurring::timer, and ast_dns_query_recurring::user_data.

Referenced by ast_dns_resolve_recurring(), and dns_query_recurring_scheduled_callback().

◆ dns_query_recurring_scheduled_callback()

static int dns_query_recurring_scheduled_callback ( const void *  data)

Scheduled recurring query callback.

Definition at line 58 of file dns_recurring.c.

59 {
60  struct ast_dns_query_recurring *recurring = (struct ast_dns_query_recurring *)data;
62  ao2_lock(recurring);
63  recurring->timer = -1;
64  if (!recurring->cancelled) {
65  recurring->active = ast_dns_resolve_async(recurring->name, recurring->rr_type, recurring->rr_class, dns_query_recurring_resolution_callback,
66  recurring);
67  }
68  ao2_unlock(recurring);
70  ao2_ref(recurring, -1);
72  return 0;
73 }

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().