/**************************************************************************** ** Project : pDirt (Aber IV Deamon) ** Module : dns.c ** Description: Asynchrone DNS lookup. Lately looking up a hostname causes ** much problems for muds. Sometimes it causes the mud to go ** "dead" for a minute or two. The way to solve this is to make ** a thread or a seperate process that will do the lookup for ** you. This module uses a seperate process to do it (supplied in ** the utils directory). ** Author : Peter Eussen ** Copyright : Part of the pDirt distribution. ** Date : 6 Dec 1997 ** Version : 1.0 *****************************************************************************/ #include "kernel.h" #include <unistd.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <netdb.h> #include <fcntl.h> #include "dns.h" #include "AberChat/client.h" #include "log.h" #include "mud.h" #include "s_socket.h" #include "mobile.h" #include "bprintf.h" #define DNSSERVERPORT 12000 int dnsfd = -1; /** FUNCTION: bootmuddns(void) ** ** This function tries to open a connection to the external DNS lookup system ** which should be running on the designated port. If it fails it will return ** -1, otherwise it will return the fd which is used for dns lookup. ** ** INPUT : none ** OUTPUT: -1 if boot failed ** fd >= 0 if boot succeeded. **/ int bootmuddns() { extern fd_set sockets_fds; static Boolean warn = True; if (dnsfd == -1) { dnsfd = makesock(my_hostname,DNSSERVERPORT); if (dnsfd != -1) { FD_SET(dnsfd,&sockets_fds); mudlog("MUDDNS: DNS Connection established."); } else if (warn) { warn = False; progerror("MUDDNS"); } } else FD_SET(dnsfd,&sockets_fds); return dnsfd; } /** FUNCTION: closemuddns(void) ** ** This function closed the connection with the muddns system. ** It will remove the fd from the listen list, close the fd and log to the ** syslog that the connection has been closed. ** ** INPUT : none ** OUTPUT: none **/ void closemuddns() { extern fd_set sockets_fds; FD_CLR(dnsfd,&sockets_fds); shutdown(dnsfd,2); close(dnsfd); dnsfd = -1; mudlog("MUDDNS: DNS Connection has been closed."); } /** FUNCTION: request_lookup() ** ** This function puts a request to the external dns lookup system for a ** specified socket of the mud. ** ** INPUT : int plr = socket of the mud which should be resolved. ** char *ip= the ip-number which should be translated to a hostname ** OUTPUT: none **/ void request_lookup(int plr, char *ip) { char line[19]; sprintf(line,"%d:%s",plr,ip); write(dnsfd,line,19); } /** FUNCTION: read_lookup() ** ** Reads a finished host lookup. Once the request_lookup has been entered, ** the dns will go to it and try to resolve it. Once it is finished it will ** send back the result. This function reads that result and does the ** appropriate actions. ** ** INPUT : int fd = the dns fd ** OUTPUT: none **/ void read_lookup(int fd) { char line[120]; /* The size of a record returned by dnssystem */ char host[100]; /* Temp storage for the hostname */ char newhost[100]; /* Full hostname including ban characters */ char *s = newhost; /* Pointer for adding bann characters */ int i; /* Temp storage for socket number */ Boolean banned_host = False; /* Is the host banned? */ Boolean locked_host = False; /* Is the host locked? */ /* Try to read a record from the dnsfd, if it fails then it means the * external dns program crashed. So close the connection to avoid havoc * and to switch back to the old mode lookup */ if ((i = read(fd,line,120)) < 1) closemuddns(); else { /* Okay, we have a record here, now lets disect it into a socket number * and a hostname. After that is done check if the socket is valid, cause * if it isnt, then something went wrong. */ sscanf(line,"%d:%s",&i,host); if (i < 0 || i > max_players) return; /* Check for host banns */ banned_host = is_host_banned(host); locked_host = is_locked_host(host); /* Add signs to denote what kind of lock the host has, '*' means banned * '!' means locked. */ if (banned_host) *s++ = '*'; else if (locked_host) *s++ = '!'; /* Now add the hostname to it and we're all set to copy it to the targets */ strcpy(s,host); strncpy(players[i].realhostname,newhost,MAXHOSTNAMELEN); strncpy(players[i].hostname,newhost,MAXHOSTNAMELEN); /* This host cant log in, so let's not wait for it to do anything but * kick it out with the appropriate message. */ if (banned_host) { int save_mynum = mynum; setup_globals(i); bprintf("\n\001f"BAN_MSG2"\003\n"); crapup(NULL,CRAP_RETURN); setup_globals(save_mynum); } /* If the lookup took very long it may occur that the player has already * logged in, so make sure the fake hostname is placed when that happens */ if (ublock[i].pname[0] != '\0' && players[i].iamon) find_fake_host_name(pname(i),host,players[i].hostname); } }