aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/librdns/util.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2022-01-02 23:53:55 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2022-01-02 23:53:55 +0000
commit3aec3589a45dd71191f47da93656b6b5614903de (patch)
treeed846a6325d6754faf2ad6b6ab0d38e2c3a19a35 /contrib/librdns/util.c
parentbe5153fa1b8cc23b03e616fc0288b9f1994754d8 (diff)
downloadrspamd-3aec3589a45dd71191f47da93656b6b5614903de.tar.gz
rspamd-3aec3589a45dd71191f47da93656b6b5614903de.zip
[Project] Rdns: Add reaper for inactive TCP connections
Diffstat (limited to 'contrib/librdns/util.c')
-rw-r--r--contrib/librdns/util.c124
1 files changed, 101 insertions, 23 deletions
diff --git a/contrib/librdns/util.c b/contrib/librdns/util.c
index e33ab709c..61c244199 100644
--- a/contrib/librdns/util.c
+++ b/contrib/librdns/util.c
@@ -515,8 +515,15 @@ rdns_ioc_free (struct rdns_io_channel *ioc)
ioc->resolver->async->del_read (ioc->resolver->async->data,
ioc->async_io);
kh_destroy(rdns_requests_hash, ioc->requests);
- close (ioc->sock);
- free (ioc->saddr);
+
+ if (ioc->sock != -1) {
+ close(ioc->sock);
+ }
+
+ if (ioc->saddr != NULL) {
+ free(ioc->saddr);
+ }
+
free (ioc);
}
@@ -553,28 +560,12 @@ rdns_ioc_new (struct rdns_server *serv,
if (is_tcp) {
/* We also need to connect a TCP channel and set a TCP buffer */
nioc->tcp = (struct rdns_tcp_channel *)(((unsigned char *)nioc) + sizeof(*nioc));
- int r = connect (nioc->sock, nioc->saddr, nioc->slen);
-
- if (r == -1) {
- if (errno != EAGAIN && errno != EINTR && errno != EINPROGRESS) {
- rdns_err ("cannot connect a TCP socket: %s for server %s",
- strerror(errno), serv->name);
- close(nioc->sock);
- free(nioc);
- return NULL;
- }
- else {
- /* We need to wait for write readiness here */
- nioc->async_io = resolver->async->add_write (resolver->async->data,
- nioc->sock, nioc);
- }
- }
- else {
- /* Always be ready to read from a TCP socket */
- nioc->flags |= RDNS_CHANNEL_CONNECTED|RDNS_CHANNEL_ACTIVE;
- nioc->tcp->async_read = resolver->async->add_read(resolver->async->data,
- nioc->sock, nioc);
+ if (!rdns_ioc_tcp_connect(nioc)) {
+ rdns_err ("cannot connect TCP socket to %s: %s", serv->name,
+ strerror (errno));
+ free (nioc);
+ return NULL;
}
nioc->flags |= RDNS_CHANNEL_TCP;
@@ -636,6 +627,93 @@ rdns_request_release (struct rdns_request *req)
REF_RELEASE (req);
}
+void
+rdns_ioc_tcp_reset (struct rdns_io_channel *ioc)
+{
+ struct rdns_resolver *resolver = ioc->resolver;
+
+ if (IS_CHANNEL_CONNECTED(ioc)) {
+ if (ioc->tcp->async_write) {
+ resolver->async->del_write (resolver->async->data, ioc->tcp->async_write);
+ ioc->tcp->async_write = NULL;
+ }
+ if (ioc->tcp->async_read) {
+ resolver->async->del_read (resolver->async->data, ioc->tcp->async_read);
+ ioc->tcp->async_read = NULL;
+ }
+
+ ioc->flags &= ~RDNS_CHANNEL_CONNECTED;
+ }
+
+ if (ioc->sock != -1) {
+ close (ioc->sock);
+ ioc->sock = -1;
+ }
+ if (ioc->saddr) {
+ free (ioc->saddr);
+ ioc->saddr = NULL;
+ }
+}
+
+bool
+rdns_ioc_tcp_connect (struct rdns_io_channel *ioc)
+{
+ struct rdns_resolver *resolver = ioc->resolver;
+
+ if (IS_CHANNEL_CONNECTED(ioc)) {
+ rdns_err ("trying to connect already connected IO channel!");
+ return false;
+ }
+
+ if (ioc->sock == -1) {
+ ioc->sock = rdns_make_client_socket (ioc->srv->name, ioc->srv->port,
+ SOCK_STREAM, &ioc->saddr, &ioc->slen);
+ if (ioc->sock == -1) {
+ rdns_err ("cannot open socket to %s: %s", ioc->srv->name,
+ strerror (errno));
+
+ if (ioc->saddr) {
+ free (ioc->saddr);
+ ioc->saddr = NULL;
+ }
+
+ return false;
+ }
+ }
+
+ int r = connect (ioc->sock, ioc->saddr, ioc->slen);
+
+ if (r == -1) {
+ if (errno != EAGAIN && errno != EINTR && errno != EINPROGRESS) {
+ rdns_err ("cannot connect a TCP socket: %s for server %s",
+ strerror(errno), ioc->srv->name);
+ close (ioc->sock);
+
+ if (ioc->saddr) {
+ free (ioc->saddr);
+ ioc->saddr = NULL;
+ }
+
+ ioc->sock = -1;
+
+ return false;
+ }
+ else {
+ /* We need to wait for write readiness here */
+ ioc->tcp->async_write = resolver->async->add_write (resolver->async->data,
+ ioc->sock, ioc);
+ }
+ }
+ else {
+ /* Always be ready to read from a TCP socket */
+ ioc->flags |= RDNS_CHANNEL_CONNECTED|RDNS_CHANNEL_ACTIVE;
+ ioc->tcp->async_read = resolver->async->add_read(resolver->async->data,
+ ioc->sock, ioc);
+ }
+
+ return true;
+}
+
static bool
rdns_resolver_conf_process_line (struct rdns_resolver *resolver,
const char *line, rdns_resolv_conf_cb cb, void *ud)