void resolv_cancel(struct ResolvQuery *query_handle) { struct ResolvQuery *cb_data = (struct ResolvQuery *)query_handle; struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; dns_cancel(ctx, cb_data->query); free(cb_data->query); cb_data->client_free_cb(cb_data->client_cb_data); free(cb_data); }
static void _s2s_dns_expiry(s2s_t s2s) { time_t now; char *key; dnscache_t dns = NULL; dnsres_t res = NULL; union xhashv xhv; now = time(NULL); /* dnscache timeouts */ if(xhash_iter_first(s2s->dnscache)) do { xhv.dns_val = &dns; xhash_iter_get(s2s->dnscache, (const char **) &key, NULL, xhv.val); if (dns && !dns->pending && now > dns->expiry) { log_debug(ZONE, "expiring DNS cache for %s", dns->name); xhash_iter_zap(s2s->dnscache); xhash_free(dns->results); if (dns->query != NULL) { if (dns->query->query != NULL) dns_cancel(NULL, dns->query->query); xhash_free(dns->query->hosts); xhash_free(dns->query->results); free(dns->query->name); free(dns->query); } free(dns); } else if (dns == NULL) { xhash_iter_zap(s2s->dnscache); } } while(xhash_iter_next(s2s->dnscache)); if(xhash_iter_first(s2s->dns_bad)) do { xhv.dnsres_val = &res; xhash_iter_get(s2s->dns_bad, (const char **) &key, NULL, xhv.val); if (res && now > res->expiry) { log_debug(ZONE, "expiring DNS bad host %s", res->key); xhash_iter_zap(s2s->dns_bad); free(res->key); free(res); } else if (res == NULL) { xhash_iter_zap(s2s->dns_bad); } } while(xhash_iter_next(s2s->dns_bad)); }
/*@null@*/ static PyObject* Query_cancel(Query *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) { PyErr_SetString(PyExc_TypeError, "Query.cancel() wrong arguments."); return NULL; } assert(NULL != self->resolver); if (NULL != self->q) { dns_cancel(((Resolver*)self->resolver)->ctx, self->q); // q is invalid pointer afterwards, so we forget it self->q = NULL; } Py_RETURN_NONE; }
/*@null@*/ static PyObject* Resolver_cancel(Resolver *self, PyObject *args) { Query *query = NULL; if (!PyArg_ParseTuple(args, "O", &query) || NULL == query) { PyErr_SetString(PyExc_TypeError, "Resolver.cancel(query) wrong arguments. Pass Query returned by submit_* methods."); return NULL; } if (NULL != query->q) { dns_cancel(self->ctx, query->q); // q is invalid pointer afterwards, so we forget it query->q = NULL; } Py_RETURN_NONE; }
void resolv_cancel(struct ResolvQuery *query_handle) { struct ResolvQuery *cb_data = (struct ResolvQuery *)query_handle; struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; for (int i = 0; i < sizeof(cb_data->queries) / sizeof(cb_data->queries[0]); i++) if (cb_data->queries[i] != NULL) { dns_cancel(ctx, cb_data->queries[i]); ss_free(cb_data->queries[i]); } if (cb_data->client_free_cb != NULL) { cb_data->client_free_cb(cb_data->client_cb_data); } ss_free(cb_data); }
static void _s2s_time_checks(s2s_t s2s) { conn_t conn; time_t now; char *rkey, *key; int keylen; jqueue_t q; dnscache_t dns; char *c; int c_len; union xhashv xhv; now = time(NULL); /* queue expiry */ if(s2s->check_queue > 0) { if(xhash_iter_first(s2s->outq)) do { xhv.jq_val = &q; xhash_iter_get(s2s->outq, (const char **) &rkey, &keylen, xhv.val); log_debug(ZONE, "running time checks for %.*s", keylen, rkey); c = memchr(rkey, '/', keylen); c++; c_len = keylen - (c - rkey); /* dns lookup timeout check first */ dns = xhash_getx(s2s->dnscache, c, c_len); if(dns != NULL && dns->pending) { log_debug(ZONE, "dns lookup pending for %.*s", c_len, c); if(now > dns->init_time + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "dns lookup for %.*s timed out", c_len, c); /* bounce queue */ out_bounce_route_queue(s2s, rkey, keylen, stanza_err_REMOTE_SERVER_NOT_FOUND); /* expire pending dns entry */ xhash_zap(s2s->dnscache, dns->name); xhash_free(dns->results); if (dns->query != NULL) { if (dns->query->query != NULL) dns_cancel(NULL, dns->query->query); xhash_free(dns->query->hosts); xhash_free(dns->query->results); free(dns->query->name); free(dns->query); } free(dns); } continue; } /* get the conn */ conn = xhash_getx(s2s->out_dest, c, c_len); if(conn == NULL) { if(jqueue_size(q) > 0) { /* no pending conn? perhaps it failed? */ log_debug(ZONE, "no pending connection for %.*s, bouncing %i packets in queue", c_len, c, jqueue_size(q)); /* bounce queue */ out_bounce_route_queue(s2s, rkey, keylen, stanza_err_REMOTE_SERVER_TIMEOUT); } continue; } /* connect timeout check */ if(!conn->online && now > conn->init_time + s2s->check_queue) { dnsres_t bad; char *ipport; log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] connection to %s timed out", conn->fd->fd, conn->ip, conn->port, c); if (s2s->dns_bad_timeout > 0) { /* mark this host as bad */ ipport = dns_make_ipport(conn->ip, conn->port); bad = xhash_get(s2s->dns_bad, ipport); if (bad == NULL) { bad = (dnsres_t) calloc(1, sizeof(struct dnsres_st)); bad->key = ipport; xhash_put(s2s->dns_bad, ipport, bad); } else { free(ipport); } bad->expiry = time(NULL) + s2s->dns_bad_timeout; } /* close connection as per XMPP/RFC3920 */ /* the close function will retry or bounce the queue */ sx_close(conn->s); } } while(xhash_iter_next(s2s->outq)); } /* expiry of connected routes in conn_INPROGRESS state */ if(s2s->check_queue > 0) { /* outgoing connections */ if(s2s->out_reuse) { if(xhash_iter_first(s2s->out_host)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_host, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking dialback state for outgoing conn %.*s", keylen, key); if (_s2s_check_conn_routes(s2s, conn, "outgoing")) { log_debug(ZONE, "checking pending verify requests for outgoing conn %.*s", keylen, key); if (conn->verify > 0 && now > conn->last_verify + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] dialback verify request timed out", conn->fd->fd, conn->ip, conn->port); sx_error(conn->s, stream_err_CONNECTION_TIMEOUT, "dialback verify request timed out"); sx_close(conn->s); } } } while(xhash_iter_next(s2s->out_host)); } else { if(xhash_iter_first(s2s->out_dest)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_dest, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking dialback state for outgoing conn %s (%s)", conn->dkey, conn->key); if (_s2s_check_conn_routes(s2s, conn, "outgoing")) { log_debug(ZONE, "checking pending verify requests for outgoing conn %s (%s)", conn->dkey, conn->key); if (conn->verify > 0 && now > conn->last_verify + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] dialback verify request timed out", conn->fd->fd, conn->ip, conn->port); sx_error(conn->s, stream_err_CONNECTION_TIMEOUT, "dialback verify request timed out"); sx_close(conn->s); } } } while(xhash_iter_next(s2s->out_dest)); } /* incoming open streams */ if(xhash_iter_first(s2s->in)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->in, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking dialback state for incoming conn %.*s", keylen, key); if (_s2s_check_conn_routes(s2s, conn, "incoming")) /* if the connection is still valid, check that dialbacks have been initiated */ if(!xhash_count(conn->states) && now > conn->init_time + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] no dialback started", conn->fd->fd, conn->ip, conn->port); sx_error(conn->s, stream_err_CONNECTION_TIMEOUT, "no dialback initiated"); sx_close(conn->s); } } while(xhash_iter_next(s2s->in)); /* incoming open connections (not yet streams) */ if(xhash_iter_first(s2s->in_accept)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->in_accept, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking stream connection state for incoming conn %i", conn->fd->fd); if(!conn->online && now > conn->init_time + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] stream initiation timed out", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->in_accept)); } /* keepalives */ if(s2s->out_reuse) { if(xhash_iter_first(s2s->out_host)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_host, NULL, NULL, xhv.val); if(s2s->check_keepalive > 0 && conn->last_activity > 0 && now > conn->last_activity + s2s->check_keepalive && conn->s->state >= state_STREAM) { log_debug(ZONE, "sending keepalive for %d", conn->fd->fd); sx_raw_write(conn->s, " ", 1); } } while(xhash_iter_next(s2s->out_host)); } else { if(xhash_iter_first(s2s->out_dest)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_dest, NULL, NULL, xhv.val); if(s2s->check_keepalive > 0 && conn->last_activity > 0 && now > conn->last_activity + s2s->check_keepalive && conn->s->state >= state_STREAM) { log_debug(ZONE, "sending keepalive for %d", conn->fd->fd); sx_raw_write(conn->s, " ", 1); } } while(xhash_iter_next(s2s->out_dest)); } /* idle timeouts - disconnect connections through which no packets have been sent for <idle> seconds */ if(s2s->check_idle > 0) { /* outgoing connections */ if(s2s->out_reuse) { if(xhash_iter_first(s2s->out_host)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_host, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking idle state for %.*s", keylen, key); if (conn->last_packet > 0 && now > conn->last_packet + s2s->check_idle && conn->s->state >= state_STREAM) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] idle timeout", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->out_host)); } else { if(xhash_iter_first(s2s->out_dest)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_dest, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking idle state for %s (%s)", conn->dkey, conn->key); if (conn->last_packet > 0 && now > conn->last_packet + s2s->check_idle && conn->s->state >= state_STREAM) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] idle timeout", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->out_dest)); } /* incoming connections */ if(xhash_iter_first(s2s->in)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->in, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking idle state for %.*s", keylen, key); if (conn->last_packet > 0 && now > conn->last_packet + s2s->check_idle && conn->s->state >= state_STREAM) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] idle timeout", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->in)); } return; }