Activate GANL DNS slave and remove legacy DNS slave code.

GANL's DNS slave (start_dns_slave/queue_dns_lookup/handle_dns_slave_event)
was fully implemented but never activated. Call start_dns_slave() at the
top of run_main_loop() when use_hostname is enabled. Rewire @startslave
to restart GANL's DNS slave instead of the removed legacy slave. Remove
~200 lines of dead legacy code: boot_slave(), get_slave_result(),
CleanUpSlaveSocket(), CleanUpSlaveProcess(), slave_pid, slave_socket,
and all call sites in game.cpp, predicates.cpp, and signal handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Stephen Dennis 2026-03-03 11:43:59 -07:00
parent 75c6d8bb31
commit a6f579c301
7 changed files with 33 additions and 264 deletions

View file

@ -37,36 +37,11 @@ pid_t game_pid;
#if defined(HAVE_WORKING_FORK)
pid_t slave_pid = 0;
int slave_socket = INVALID_SOCKET;
#ifdef STUB_SLAVE
pid_t stubslave_pid = 0;
int stubslave_socket = INVALID_SOCKET;
#endif // STUB_SLAVE
void CleanUpSlaveSocket(void)
{
if (!IS_INVALID_SOCKET(slave_socket))
{
shutdown(slave_socket, SD_BOTH);
if (0 == SOCKET_CLOSE(slave_socket))
{
DebugTotalSockets--;
}
slave_socket = INVALID_SOCKET;
}
}
void CleanUpSlaveProcess(void)
{
if (slave_pid > 0)
{
kill(slave_pid, SIGKILL);
waitpid(slave_pid, nullptr, 0);
}
slave_pid = 0;
}
#ifdef STUB_SLAVE
void CleanUpStubSlaveSocket(void)
{
@ -356,212 +331,6 @@ extern "C" MUX_RESULT DCL_API pipepump(void)
#endif // STUB_SLAVE
/*! \brief Lauch reverse-DNS slave process.
*
* This spawns the reverse-DNS slave process and creates a socket-oriented,
* bi-directional communiocation path between that process and this
* process. Any existing slave process is killed.
*
* \param executor dbref of Executor.
* \param caller dbref of Caller.
* \param enactor dbref of Enactor.
* \return None.
*/
void boot_slave(dbref executor, dbref caller, dbref enactor, int eval, int key)
{
UNUSED_PARAMETER(executor);
UNUSED_PARAMETER(caller);
UNUSED_PARAMETER(enactor);
UNUSED_PARAMETER(eval);
UNUSED_PARAMETER(key);
const char *pFailedFunc = nullptr;
int sv[2];
int i;
int maxfds;
#ifdef HAVE_GETDTABLESIZE
maxfds = getdtablesize();
#else // HAVE_GETDTABLESIZE
maxfds = sysconf(_SC_OPEN_MAX);
#endif // HAVE_GETDTABLESIZE
CleanUpSlaveSocket();
CleanUpSlaveProcess();
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sv) < 0)
{
pFailedFunc = "socketpair() error: ";
goto failure;
}
// Set to nonblocking.
//
if (make_nonblocking(sv[0]) < 0)
{
pFailedFunc = "make_nonblocking() error: ";
mux_close(sv[0]);
mux_close(sv[1]);
goto failure;
}
slave_pid = fork();
switch (slave_pid)
{
case -1:
pFailedFunc = "fork() error: ";
mux_close(sv[0]);
mux_close(sv[1]);
goto failure;
case 0:
// If we don't clear this alarm, the child will eventually receive a
// SIG_PROF.
//
alarm_clock.clear();
// Child. The following calls to dup2() assume only the minimal
// dup2() functionality. That is, the destination descriptor is
// always available for it, and sv[1] is never that descriptor.
// It is likely that the standard defined behavior of dup2()
// would handle the job by itself more directly, but a little
// extra code is low-cost insurance.
//
mux_close(sv[0]);
if (sv[1] != 0)
{
mux_close(0);
if (dup2(sv[1], 0) == -1)
{
_exit(1);
}
}
if (sv[1] != 1)
{
mux_close(1);
if (dup2(sv[1], 1) == -1)
{
_exit(1);
}
}
for (i = 3; i < maxfds; i++)
{
mux_close(i);
}
execlp("bin/slave", "slave", static_cast<char *>(nullptr));
_exit(1);
}
close(sv[1]);
slave_socket = sv[0];
DebugTotalSockets++;
if (make_nonblocking(slave_socket) < 0)
{
pFailedFunc = "make_nonblocking() error: ";
CleanUpSlaveSocket();
goto failure;
}
STARTLOG(LOG_ALWAYS, "NET", "SLAVE");
log_text(T("DNS lookup slave started on fd "));
log_number(slave_socket);
ENDLOG;
return;
failure:
CleanUpSlaveProcess();
STARTLOG(LOG_ALWAYS, "NET", "SLAVE");
log_text((UTF8 *)pFailedFunc);
log_number(errno);
ENDLOG;
}
// Get a result from the slave
//
static int get_slave_result(void)
{
DESC *d;
UTF8 *buf = alloc_lbuf("slave_buf");
int len = mux_read(slave_socket, buf, LBUF_SIZE-1);
if (len < 0)
{
int iSocketError = SOCKET_LAST_ERROR;
if ( iSocketError == SOCKET_EAGAIN
|| iSocketError == SOCKET_EWOULDBLOCK)
{
free_lbuf(buf);
return -1;
}
CleanUpSlaveSocket();
CleanUpSlaveProcess();
free_lbuf(buf);
STARTLOG(LOG_ALWAYS, "NET", "SLAVE");
log_text(T("read() of slave result failed. Slave stopped."));
ENDLOG;
return -1;
}
else if (0 == len)
{
free_lbuf(buf);
return -1;
}
buf[len] = '\0';
UTF8 *host_name = alloc_lbuf("slave_host_name");
UTF8 *host_address = alloc_lbuf("slave_host_address");
UTF8 *p;
if (sscanf((char *)buf, "%s %s", host_address, host_name) != 2)
{
goto Done;
}
p = (UTF8 *)strchr((char *)buf, '\n');
if (!p)
{
goto Done;
}
*p = '\0';
if (mudconf.use_hostname)
{
for (auto it = mudstate.descriptors_list.begin(); it != mudstate.descriptors_list.end(); ++it)
{
DESC* d = *it;
if (strcmp((char *)d->addr, (char *)host_address) != 0)
{
continue;
}
strncpy((char *)d->addr, (char *)host_name, 50);
d->addr[50] = '\0';
if (d->player != 0)
{
if (d->username[0])
{
atr_add_raw(d->player, A_LASTSITE, tprintf(T("%s@%s"),
d->username, d->addr));
}
else
{
atr_add_raw(d->player, A_LASTSITE, d->addr);
}
atr_add_raw(d->player, A_LASTIP, host_address);
}
}
}
Done:
free_lbuf(buf);
free_lbuf(host_name);
free_lbuf(host_address);
return 0;
}
#endif // HAVE_WORKING_FORK
#ifdef UNIX_SSL
@ -2877,19 +2646,8 @@ static void DCL_CDECL sighandler(int sig)
if ( WIFEXITED(stat_buf)
|| WIFSIGNALED(stat_buf))
{
if (child == slave_pid)
{
// The reverse-DNS slave process ended unexpectedly.
//
CleanUpSlaveSocket();
slave_pid = 0;
LogStatBuf(stat_buf, "SLAVE");
continue;
}
#ifdef STUB_SLAVE
else if (child == stubslave_pid)
if (child == stubslave_pid)
{
// The Stub slave process ended unexpectedly.
//
@ -2899,9 +2657,10 @@ static void DCL_CDECL sighandler(int sig)
continue;
}
else
#endif // STUB_SLAVE
else if ( mudconf.fork_dump
&& mudstate.dumping)
if ( mudconf.fork_dump
&& mudstate.dumping)
{
mudstate.dumped = child;
if (mudstate.dumper == mudstate.dumped)
@ -2936,11 +2695,11 @@ static void DCL_CDECL sighandler(int sig)
#if defined(HAVE_WORKING_FORK)
STARTLOG(LOG_PROBLEMS, "SIG", "DEBUG");
#ifdef STUB_SLAVE
Log.tinyprintf(T("mudstate.dumper=%d, child=%d, slave_pid=%d, stubslave_pid=%d" ENDLINE),
mudstate.dumper, child, slave_pid, stubslave_pid);
Log.tinyprintf(T("mudstate.dumper=%d, child=%d, stubslave_pid=%d" ENDLINE),
mudstate.dumper, child, stubslave_pid);
#else
Log.tinyprintf(T("mudstate.dumper=%d, child=%d, slave_pid=%d" ENDLINE),
mudstate.dumper, child, slave_pid);
Log.tinyprintf(T("mudstate.dumper=%d, child=%d" ENDLINE),
mudstate.dumper, child);
#endif // STUB_SLAVE
ENDLOG;
#endif // HAVE_WORKING_FORK
@ -3068,9 +2827,6 @@ static void DCL_CDECL sighandler(int sig)
#if defined(UNIX_PROCESSES)
#if defined(HAVE_WORKING_FORK)
CleanUpSlaveSocket();
CleanUpSlaveProcess();
// Try our best to dump a core first
//
if (!fork())

View file

@ -11,6 +11,7 @@
#include "autoconf.h"
#include "config.h"
#include "externs.h"
#include "ganl_adapter.h"
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
@ -591,9 +592,7 @@ static CMDENT_NO_ARG command_table_no_arg[] =
{T("@mark_all"), markall_sw, CA_WIZARD, MARK_SET, CS_NO_ARGS, 0, do_markall},
{T("@readcache"), nullptr, CA_WIZARD, 0, CS_NO_ARGS, 0, do_readcache},
{T("@restart"), nullptr, CA_NO_GUEST|CA_NO_SLAVE, 0, CS_NO_ARGS, 0, do_restart},
#if defined(HAVE_WORKING_FORK)
{T("@startslave"), nullptr, CA_WIZARD, 0, CS_NO_ARGS, 0, boot_slave},
#endif // HAVE_WORKING_FORK
{T("@startslave"), nullptr, CA_WIZARD, 0, CS_NO_ARGS, 0, do_startslave},
{T("@timecheck"), timecheck_sw, CA_WIZARD, 0, CS_NO_ARGS, 0, do_timecheck},
{T("clearcom"), nullptr, CA_NO_SLAVE, 0, CS_NO_ARGS, 0, do_clearcom},
{T("info"), nullptr, CA_PUBLIC, CMD_INFO, CS_NO_ARGS, 0, logged_out0},

View file

@ -2983,8 +2983,6 @@ int DCL_CDECL main(int argc, char *argv[])
CLOSE;
#if defined(HAVE_WORKING_FORK)
CleanUpSlaveSocket();
CleanUpSlaveProcess();
#ifdef STUB_SLAVE
CleanUpStubSlaveSocket();
WaitOnStubSlaveProcess();

View file

@ -1706,6 +1706,11 @@ void GanlAdapter::prepare_for_restart() {
void GanlAdapter::run_main_loop() {
Log.WriteString(T("GANL: Entering main loop.\n"));
Log.Flush();
if (mudconf.use_hostname) {
start_dns_slave();
}
ltaLastSlice_.GetUTC();
// Calculate available descriptor limit, reserving 7 for system use
@ -2380,3 +2385,19 @@ void ganl_associate_player(DESC* d, dbref player) {
d->player = player;
}
}
void do_startslave(dbref executor, dbref caller, dbref enactor,
int eval, int key)
{
UNUSED_PARAMETER(caller);
UNUSED_PARAMETER(enactor);
UNUSED_PARAMETER(eval);
UNUSED_PARAMETER(key);
g_GanlAdapter.shutdown_dns_slave();
if (g_GanlAdapter.start_dns_slave()) {
notify(executor, T("DNS slave restarted."));
} else {
notify(executor, T("DNS slave failed to start."));
}
}

View file

@ -144,5 +144,7 @@ void ganl_main_loop();
void ganl_send_data_str(DESC* d, const UTF8* data);
void ganl_close_connection(DESC* d, int reason); // TinyMUX reason codes
void ganl_associate_player(DESC* d, dbref player); // Needed after successful login
void do_startslave(dbref executor, dbref caller, dbref enactor,
int eval, int key);
#endif // GANL_ADAPTER_H

View file

@ -311,11 +311,6 @@ int mux_getaddrinfo(const UTF8 *node, const UTF8 *service, const MUX_ADDRINFO *h
void mux_freeaddrinfo(MUX_ADDRINFO *res);
int mux_getnameinfo(const mux_sockaddr *msa, UTF8 *host, size_t hostlen, UTF8 *serv, size_t servlen, int flags);
#if defined(HAVE_WORKING_FORK)
void boot_slave(dbref executor, dbref caller, dbref enactor, int eval, int key);
#endif
#if defined(HAVE_WORKING_FORK)
void CleanUpSlaveSocket(void);
void CleanUpSlaveProcess(void);
#ifdef STUB_SLAVE
void CleanUpStubSlaveSocket(void);
void WaitOnStubSlaveProcess(void);

View file

@ -1639,8 +1639,6 @@ void do_restart(dbref executor, dbref caller, dbref enactor, int eval, int key)
#elif defined(UNIX_PROCESSES)
#if defined(HAVE_WORKING_FORK)
dump_restart_db();
CleanUpSlaveSocket();
CleanUpSlaveProcess();
#endif // HAVE_WORKING_FORK
Log.StopLogging();