Browse Source

[Fix] Add guards to avoid race condition on TCP connection

tags/3.2
Vsevolod Stakhov 2 years ago
parent
commit
c790a8db04
3 changed files with 18 additions and 2 deletions
  1. 1
    0
      contrib/librdns/dns_private.h
  2. 1
    0
      contrib/librdns/resolver.c
  3. 16
    2
      contrib/librdns/util.c

+ 1
- 0
contrib/librdns/dns_private.h View File

@@ -142,6 +142,7 @@ enum rdns_io_channel_flags {
RDNS_CHANNEL_CONNECTED = 1u << 0u,
RDNS_CHANNEL_ACTIVE = 1u << 1u,
RDNS_CHANNEL_TCP = 1u << 2u,
RDNS_CHANNEL_TCP_CONNECTING = 1u << 3u,
};

#define IS_CHANNEL_CONNECTED(ioc) (((ioc)->flags & RDNS_CHANNEL_CONNECTED) != 0)

+ 1
- 0
contrib/librdns/resolver.c View File

@@ -431,6 +431,7 @@ static void
rdns_process_tcp_connect (int fd, struct rdns_io_channel *ioc)
{
ioc->flags |= RDNS_CHANNEL_CONNECTED|RDNS_CHANNEL_ACTIVE;
ioc->flags &= ~RDNS_CHANNEL_TCP_CONNECTING;

if (ioc->tcp->async_read == NULL) {
ioc->tcp->async_read = ioc->resolver->async->add_read(ioc->resolver->async->data,

+ 16
- 2
contrib/librdns/util.c View File

@@ -730,6 +730,12 @@ rdns_ioc_tcp_connect (struct rdns_io_channel *ioc)
return false;
}

if (ioc->flags & RDNS_CHANNEL_TCP_CONNECTING) {
/* Already connecting channel, ignore connect request */

return true;
}

if (ioc->sock == -1) {
ioc->sock = rdns_make_client_socket (ioc->srv->name, ioc->srv->port,
SOCK_STREAM, &ioc->saddr, &ioc->slen);
@@ -765,13 +771,21 @@ rdns_ioc_tcp_connect (struct rdns_io_channel *ioc)
}
else {
/* We need to wait for write readiness here */
ioc->tcp->async_write = resolver->async->add_write (resolver->async->data,
ioc->sock, ioc);
if (ioc->tcp->async_write != NULL) {
rdns_err("internal rdns error: write event is already registered on connect");
}
else {
ioc->tcp->async_write = resolver->async->add_write(resolver->async->data,
ioc->sock, ioc);
}
/* Prevent double connect attempts */
ioc->flags |= RDNS_CHANNEL_TCP_CONNECTING;
}
}
else {
/* Always be ready to read from a TCP socket */
ioc->flags |= RDNS_CHANNEL_CONNECTED|RDNS_CHANNEL_ACTIVE;
ioc->flags &= ~RDNS_CHANNEL_TCP_CONNECTING;
ioc->tcp->async_read = resolver->async->add_read(resolver->async->data,
ioc->sock, ioc);
}

Loading…
Cancel
Save