guint weight;
guint cur_weight;
guint errors;
+ guint dns_requests;
gint active_idx;
gchar *name;
struct event ev;
rspamd_mutex_unlock (ls->lock);
}
-static void
-rspamd_upstream_dns_cb (struct rdns_reply *reply, void *arg)
-{
- struct upstream *up = (struct upstream *)arg;
- struct rdns_reply_entry *entry;
- struct upstream_inet_addr_entry *up_ent;
-
- if (reply->code == RDNS_RC_NOERROR) {
- entry = reply->entries;
-
- rspamd_mutex_lock (up->lock);
- while (entry) {
-
- if (entry->type == RDNS_REQUEST_A) {
- up_ent = g_malloc0 (sizeof (*up_ent));
- up_ent->addr = rspamd_inet_address_new (AF_INET,
- &entry->content.a.addr);
- LL_PREPEND (up->new_addrs, up_ent);
- }
- else if (entry->type == RDNS_REQUEST_AAAA) {
- up_ent = g_malloc0 (sizeof (*up_ent));
- up_ent->addr = rspamd_inet_address_new (AF_INET6,
- &entry->content.aaa.addr);
- LL_PREPEND (up->new_addrs, up_ent);
- }
- entry = entry->next;
- }
- rspamd_mutex_unlock (up->lock);
- }
-
- REF_RELEASE (up);
-}
-
static void
rspamd_upstream_update_addrs (struct upstream *up)
{
* We need first of all get the saved port, since DNS gives us no
* idea about what port has been used previously
*/
+ rspamd_mutex_lock (up->lock);
+
if (up->addrs.addr->len > 0 && up->new_addrs) {
- port = rspamd_inet_address_get_port (g_ptr_array_index (up->addrs.addr, 0));
+ port = rspamd_inet_address_get_port (g_ptr_array_index (up->addrs.addr,
+ 0));
/* Free old addresses */
g_ptr_array_free (up->addrs.addr, TRUE);
/* Now calculate new addrs count */
addr_cnt = 0;
LL_FOREACH (up->new_addrs, cur) {
- addr_cnt ++;
+ addr_cnt++;
}
new_addrs = g_ptr_array_new_full (addr_cnt,
- (GDestroyNotify)rspamd_inet_address_destroy);
+ (GDestroyNotify) rspamd_inet_address_destroy);
/* Copy addrs back */
LL_FOREACH (up->new_addrs, cur) {
g_free (cur);
}
up->new_addrs = NULL;
+
+ rspamd_mutex_unlock (up->lock);
+}
+
+static void
+rspamd_upstream_dns_cb (struct rdns_reply *reply, void *arg)
+{
+ struct upstream *up = (struct upstream *)arg;
+ struct rdns_reply_entry *entry;
+ struct upstream_inet_addr_entry *up_ent;
+
+ if (reply->code == RDNS_RC_NOERROR) {
+ entry = reply->entries;
+
+ rspamd_mutex_lock (up->lock);
+ while (entry) {
+
+ if (entry->type == RDNS_REQUEST_A) {
+ up_ent = g_malloc0 (sizeof (*up_ent));
+ up_ent->addr = rspamd_inet_address_new (AF_INET,
+ &entry->content.a.addr);
+ LL_PREPEND (up->new_addrs, up_ent);
+ }
+ else if (entry->type == RDNS_REQUEST_AAAA) {
+ up_ent = g_malloc0 (sizeof (*up_ent));
+ up_ent->addr = rspamd_inet_address_new (AF_INET6,
+ &entry->content.aaa.addr);
+ LL_PREPEND (up->new_addrs, up_ent);
+ }
+ entry = entry->next;
+ }
+
+ rspamd_mutex_unlock (up->lock);
+ }
+
+ up->dns_requests--;
+
+ if (up->dns_requests == 0) {
+ rspamd_upstream_update_addrs (up);
+ }
+
+ REF_RELEASE (up);
}
static void
event_del (&up->ev);
if (up->ls) {
rspamd_upstream_set_active (up->ls, up);
-
- if (up->new_addrs) {
- rspamd_upstream_update_addrs (up);
- }
}
rspamd_mutex_unlock (up->lock);
if (rdns_make_request_full (up->ctx->res, rspamd_upstream_dns_cb, up,
up->ctx->dns_timeout, up->ctx->dns_retransmits,
1, up->name, RDNS_REQUEST_A) != NULL) {
+ up->dns_requests ++;
REF_RETAIN (up);
}
if (rdns_make_request_full (up->ctx->res, rspamd_upstream_dns_cb, up,
up->ctx->dns_timeout, up->ctx->dns_retransmits,
1, up->name, RDNS_REQUEST_AAAA) != NULL) {
+ up->dns_requests ++;
REF_RETAIN (up);
}
}
/* Here the upstreams list is already locked */
rspamd_mutex_lock (up->lock);
event_del (&up->ev);
-
- if (up->new_addrs) {
- rspamd_upstream_update_addrs (up);
- }
-
g_ptr_array_add (ups->alive, up);
up->active_idx = ups->alive->len - 1;
rspamd_mutex_unlock (up->lock);
/* Silent stupid compilers */
return NULL;
}
+
+void
+rspamd_upstream_reresolve (struct upstream_ctx *ctx)
+{
+ GList *cur;
+ struct upstream *up;
+
+ cur = ctx->upstreams->head;
+
+ while (cur) {
+ up = cur->data;
+
+ if (up->name[0] != '/') {
+ if (rdns_make_request_full (ctx->res,
+ rspamd_upstream_dns_cb,
+ up,
+ ctx->dns_timeout,
+ ctx->dns_retransmits,
+ 1,
+ up->name,
+ RDNS_REQUEST_A) != NULL) {
+ up->dns_requests++;
+ REF_RETAIN (up);
+ }
+
+ if (rdns_make_request_full (ctx->res,
+ rspamd_upstream_dns_cb,
+ up,
+ ctx->dns_timeout,
+ ctx->dns_retransmits,
+ 1,
+ up->name,
+ RDNS_REQUEST_AAAA) != NULL) {
+ up->dns_requests++;
+ REF_RETAIN (up);
+ }
+ }
+
+ cur = g_list_next (cur);
+ }
+}