Memleak in EM.connect when name resolution fails · Issue #987 · eventmachine/eventmachine · GitHub
Skip to content

Memleak in EM.connect when name resolution fails #987

Open

Description

@paddor

EventMachine 1.2.7
Ruby 3.3.1
OS: Ubuntu 22.04

There's a memleak when the DNS resolver of EM.connect fails, e.g. when /etc/hosts don't contain the entry.
If I do a Resolv.getaddress before the EM.connect, no memory is leaked.

Minimal reproduction:

require 'eventmachine'
require 'resolv'

module MyClient
  def post_init
    puts "post_init"
  end

  def receive_data data
    puts "received: #{data}"
  end

  def unbind
    puts "terminated"
  end
end


NAME = 'name.does.not.exist'


EM.run do
  loop do
    print '.'

    # ip = Resolv.getaddress NAME
    # EM.connect ip, 80, MyClient # no leak

    EM.connect NAME, 80, MyClient  # leak
  rescue EM::ConnectionError, Resolv::ResolvError
  end
end

Activity

  1. paddor commented on Jul 3, 2024

    @paddor
    ContributorAuthor

    I think freeaddrinfo() in EventMachine_t::name2address needs to be called unconditionally:

    EDIT: That does not help unfortunately.

    I tried this:

    int EventMachine_t::name2address (const char *server, int port, int socktype, struct sockaddr *addr, size_t *addr_len)
    {
      printf("!");
    	if (!server || !*server)
    		server = "0.0.0.0";
    
    	struct addrinfo *ai = NULL;
    	struct addrinfo hints;
    	memset (&hints, 0, sizeof(hints));
    	hints.ai_socktype = socktype;
    	hints.ai_family = AF_UNSPEC;
    	hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
    
    	char portstr[12];
    	snprintf(portstr, sizeof(portstr), "%u", port);
    
    	int gai = getaddrinfo (server, portstr, &hints, &ai);
    	if (gai == 0) {
    		assert (ai->ai_addrlen <= *addr_len);
    		memcpy (addr, ai->ai_addr, ai->ai_addrlen);
    		*addr_len = ai->ai_addrlen;
    	}
    
    	freeaddrinfo(ai);
    
    	return gai;
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions