Asterisk - The Open Source Telephony Project  18.5.0
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.

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

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in 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.

Parameters
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
NULLfailure
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 109 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().

110 {
111  struct ast_dns_query_recurring *recurring;
112 
114  return NULL;
115  }
116 
117  recurring = ao2_alloc(sizeof(*recurring) + strlen(name) + 1, dns_query_recurring_destroy);
118  if (!recurring) {
119  return NULL;
120  }
121 
122  recurring->callback = callback;
123  recurring->user_data = ao2_bump(data);
124  recurring->timer = -1;
125  recurring->rr_type = rr_type;
126  recurring->rr_class = rr_class;
127  strcpy(recurring->name, name); /* SAFE */
128 
130  if (!recurring->active) {
131  ao2_ref(recurring, -1);
132  return NULL;
133  }
134 
135  return recurring;
136 }
ast_dns_resolve_callback callback
Callback to invoke upon completion.
Definition: dns_internal.h:159
char name[0]
The name of what is being resolved.
Definition: dns_internal.h:173
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
int rr_class
Resource record class.
Definition: dns_internal.h:171
static void dns_query_recurring_destroy(void *data)
Destructor for a DNS query.
Definition: dns_recurring.c:43
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_bump(obj)
Definition: astobj2.h:491
void * user_data
User-specific data.
Definition: dns_internal.h:161
struct ast_sched_context * ast_dns_get_sched(void)
Retrieve the DNS scheduler context.
Definition: dns_core.c:52
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_dns_query_active * active
Current active query.
Definition: dns_internal.h:163
static void dns_query_recurring_resolution_callback(const struct ast_dns_query *query)
Query resolution callback.
Definition: dns_recurring.c:71
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
A recurring DNS query.
Definition: dns_internal.h:157
int rr_type
Resource record type.
Definition: dns_internal.h:169
int timer
Scheduled timer for next resolution.
Definition: dns_internal.h:167

◆ ast_dns_resolve_recurring_cancel()

int ast_dns_resolve_recurring_cancel ( struct ast_dns_query_recurring recurring)

Cancel an asynchronous recurring DNS resolution.

Parameters
queryThe 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
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 138 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().

139 {
140  int res = 0;
141 
142  ao2_lock(recurring);
143 
144  recurring->cancelled = 1;
145  AST_SCHED_DEL_UNREF(ast_dns_get_sched(), recurring->timer, ao2_ref(recurring, -1));
146 
147  if (recurring->active) {
148  res = ast_dns_resolve_cancel(recurring->active);
149  ao2_replace(recurring->active, NULL);
150  }
151 
152  ao2_unlock(recurring);
153 
154  return res;
155 }
#define AST_SCHED_DEL_UNREF(sched, id, refcall)
schedule task to get deleted and call unref function
Definition: sched.h:80
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct ast_sched_context * ast_dns_get_sched(void)
Retrieve the DNS scheduler context.
Definition: dns_core.c:52
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_dns_query_active * active
Current active query.
Definition: dns_internal.h:163
#define ao2_lock(a)
Definition: astobj2.h:718
unsigned int cancelled
The recurring query has been cancelled.
Definition: dns_internal.h:165
#define ao2_replace(dst, src)
Definition: astobj2.h:517
int ast_dns_resolve_cancel(struct ast_dns_query_active *active)
Cancel an asynchronous DNS resolution.
Definition: dns_core.c:272
int timer
Scheduled timer for next resolution.
Definition: dns_internal.h:167

◆ dns_query_recurring_destroy()

static void dns_query_recurring_destroy ( void *  data)
static

Destructor for a DNS query.

Definition at line 43 of file dns_recurring.c.

References ao2_cleanup, dns_query_recurring_resolution_callback(), and ast_dns_query_recurring::user_data.

Referenced by ast_dns_resolve_recurring().

44 {
45  struct ast_dns_query_recurring *recurring = data;
46 
47  ao2_cleanup(recurring->user_data);
48 }
void * user_data
User-specific data.
Definition: dns_internal.h:161
A recurring DNS query.
Definition: dns_internal.h:157
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ dns_query_recurring_resolution_callback()

static void dns_query_recurring_resolution_callback ( const struct ast_dns_query query)
static

Query resolution callback.

Definition at line 71 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::callback, ast_dns_query_recurring::callback, ast_dns_query_recurring::cancelled, dns_query_alloc(), dns_query_recurring_scheduled_callback(), 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(), dns_query_recurring_destroy(), and dns_query_recurring_scheduled_callback().

72 {
73  struct ast_dns_query_recurring *recurring = ast_dns_query_get_data(query);
74  struct ast_dns_query *callback_query;
75 
76  /* Create a separate query to invoke the user specific callback on as the
77  * recurring query user data may get used externally (by the unit test)
78  * and thus changing it is problematic
79  */
80  callback_query = dns_query_alloc(query->name, query->rr_type, query->rr_class,
81  recurring->callback, recurring->user_data);
82  if (callback_query) {
83  /* The result is immutable at this point and can be safely provided */
84  callback_query->result = query->result;
85  callback_query->callback(callback_query);
86  callback_query->result = NULL;
87  ao2_ref(callback_query, -1);
88  }
89 
90  ao2_lock(recurring);
91  /* So.. if something has not externally cancelled this we can reschedule based on the TTL */
92  if (!recurring->cancelled) {
93  const struct ast_dns_result *result = ast_dns_query_get_result(query);
94  int ttl = MIN(ast_dns_result_get_lowest_ttl(result), INT_MAX / 1000);
95 
96  if (ttl) {
98  if (recurring->timer < 0) {
99  /* It is impossible for this to be the last reference as the query has a reference to it */
100  ao2_ref(recurring, -1);
101  }
102  }
103  }
104 
105  ao2_replace(recurring->active, NULL);
106  ao2_unlock(recurring);
107 }
ast_dns_resolve_callback callback
Callback to invoke upon completion.
Definition: dns_internal.h:159
int rr_type
Resource record type.
Definition: dns_internal.h:149
int rr_class
Resource record class.
Definition: dns_internal.h:151
static int dns_query_recurring_scheduled_callback(const void *data)
Scheduled recurring query callback.
Definition: dns_recurring.c:53
#define ao2_unlock(a)
Definition: astobj2.h:730
char name[0]
The name of what is being resolved.
Definition: dns_internal.h:153
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
#define MIN(a, b)
Definition: utils.h:226
void * user_data
User-specific data.
Definition: dns_internal.h:161
struct ast_sched_context * ast_dns_get_sched(void)
Retrieve the DNS scheduler context.
Definition: dns_core.c:52
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
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
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
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_dns_query_active * active
Current active query.
Definition: dns_internal.h:163
#define ao2_lock(a)
Definition: astobj2.h:718
The result of a DNS query.
Definition: dns_internal.h:117
unsigned int cancelled
The recurring query has been cancelled.
Definition: dns_internal.h:165
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
struct ast_dns_result * result
Result of the DNS query.
Definition: dns_internal.h:147
ast_dns_resolve_callback callback
Callback to invoke upon completion.
Definition: dns_internal.h:139
A DNS query.
Definition: dns_internal.h:137
A recurring DNS query.
Definition: dns_internal.h:157
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:565
#define ao2_replace(dst, src)
Definition: astobj2.h:517
static PGresult * result
Definition: cel_pgsql.c:88
int timer
Scheduled timer for next resolution.
Definition: dns_internal.h:167

◆ dns_query_recurring_scheduled_callback()

static int dns_query_recurring_scheduled_callback ( const void *  data)
static

Scheduled recurring query callback.

Definition at line 53 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().

54 {
55  struct ast_dns_query_recurring *recurring = (struct ast_dns_query_recurring *)data;
56 
57  ao2_lock(recurring);
58  recurring->timer = -1;
59  if (!recurring->cancelled) {
60  recurring->active = ast_dns_resolve_async(recurring->name, recurring->rr_type, recurring->rr_class, dns_query_recurring_resolution_callback,
61  recurring);
62  }
63  ao2_unlock(recurring);
64 
65  ao2_ref(recurring, -1);
66 
67  return 0;
68 }
char name[0]
The name of what is being resolved.
Definition: dns_internal.h:173
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
int rr_class
Resource record class.
Definition: dns_internal.h:171
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_dns_query_active * active
Current active query.
Definition: dns_internal.h:163
#define ao2_lock(a)
Definition: astobj2.h:718
unsigned int cancelled
The recurring query has been cancelled.
Definition: dns_internal.h:165
static void dns_query_recurring_resolution_callback(const struct ast_dns_query *query)
Query resolution callback.
Definition: dns_recurring.c:71
A recurring DNS query.
Definition: dns_internal.h:157
int rr_type
Resource record type.
Definition: dns_internal.h:169
int timer
Scheduled timer for next resolution.
Definition: dns_internal.h:167