Skip to content

multiple listen socket#40

Open
Slash333 wants to merge 1 commit into
Karlson2k:masterfrom
Slash333:feature/multiple_listen_socket_single_daemon
Open

multiple listen socket#40
Slash333 wants to merge 1 commit into
Karlson2k:masterfrom
Slash333:feature/multiple_listen_socket_single_daemon

Conversation

@Slash333
Copy link
Copy Markdown

Allow a single MHD daemon to bind multiple listen sockets

MHD_OPTION_SOCK_ADDR and MHD_OPTION_SOCK_ADDR_LEN can now be passed multiple times (up to 8); each occurrence adds one listen socket.

  • struct MHD_Daemon gains listen_fds[]/num_listen_fds; the legacy listen_fd is preserved and kept in sync with listen_fds[0].
  • The inline bind/listen block in MHD_start_daemon_va() is factored into create_one_listen_socket_(), called once per sockaddr.
  • select / poll / epoll and the external-fdset paths iterate listen_fds[]; MHD_accept_connection() takes the listen fd as an argument. The epoll acceptor round-robins across sockets, still capped at 10 accepts per turn.
  • MHD_quiesce_daemon() and MHD_stop_daemon() iterate every listen fd (stop still skips close when the daemon was quiesced).

No behaviour change for daemons configured with zero or one sockaddr.

@Karlson2k
Copy link
Copy Markdown
Owner

Karlson2k commented May 19, 2026

Hi Igor,

Thank you for your PR.
Before going into details: why don't you use existing functionality? You can simply run multiple daemons with the same parameters except the listen socket address. Or you can create and use as many listen sockets as you want and then use MHD_add_connection() for new connections. In case of multiple worker daemons this will work even better than internal mechanism due to more even distribution of load to the daemons.

By briefly checking you patch, I found a few things:

  • artificial limitation of 8 listen sockets does not look good. It could be a dynamic number;
  • default number of maximum connection has not changed, while it is important for non-W32 systems using select();
  • all but the first listen sockets are leaked (and never closed) when MHD_quiesce_daemon() is used;
  • failure to add listen socket to epoll FD is handled as non-critical error (this is fine), but failure of removing of any of listen sockets from epoll FD triggers PANIC(), which is wrong in this design as any listen socket could be outside epoll FD in functional daemon;
  • if any listening socket has pending connection than listen() is called for every listening socket in epoll mode, which costly.

There may be other issues in the code as it has not been reviewed in details.
However, before going into deeper details, I'd like to understand, why existing MHD mechanisms cannot be used for the same purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants