/******************************************************************************
** Project : pDirt (Aber IV Daemon)
** Module : utils/dnsresolv/dns.c (MUDDNS)
** Description: The 2nd part to DNS asynchrone lookup. It will read a records
** of 19 bytes and return records of 120 bytes.
** INPUT: <nr>:<ip number>.... May not fill the complete 19 bytes
** but it expects 19 bytes!!
** OUTPUT: <nr>:<hostnumber>... Again.. it will write 120 bytes,
** so expect 120 bytes!
** nr = the socket number inside the mud.
** Author : Peter Eussen
** Date : 6 Dec 1997
** Version : 1.0
****************************************************************************/
#include "kernel.h"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <unistd.h>
#include "trie.h"
#define SERVERPORT 12000 /* Port the MudDNS listens to */
#define BUFFERDNS /* Buffer IP's or not? undef
* for low mem machines.
*/
int makesock(void);
void read_request(int fd);
void new_conn(int mainfd);
int daemonize(void);
void openLog(void);
fd_set input_set,all_set;
int width;
FILE *logfile;
int main()
{ int main_sock,fd,numavail;
if (daemonize() == -1)
{ printf("Failed to daemonize.\n");
return -2;
}
fclose(stderr);
fclose(stdout);
fclose(stdin);
openLog();
if ((main_sock = makesock()) == -1)
{ fprintf(logfile,"BOOT: Could not connect to socket. Already running?\n");
fclose(logfile);
return -1;
}
width = main_sock+1;
FD_ZERO(&input_set);
FD_ZERO(&all_set);
FD_SET(main_sock,&input_set);
FD_SET(main_sock,&all_set);
while (1)
{ input_set = all_set;
numavail = select(width,&input_set,NULL,NULL,NULL);
for (fd = 0; numavail > 0; fd++)
{ if (FD_ISSET(fd,&input_set))
{ if (fd == main_sock)
new_conn(fd);
else
read_request(fd);
numavail--;
}
}
}
return 0;
}
int makesock(void) {
int sock;
char opt = 1;
struct sockaddr_in sin;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(logfile,"BOOT: Unable to create socket.\n");
return(-1);
}
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sin.sin_family = AF_INET;
sin.sin_port = htons (SERVERPORT);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock, (struct sockaddr *) &sin, sizeof (sin)) == -1) {
fprintf(logfile,"BOOT: MudDNS, error in bind.\n");
return(-1);
}
listen(sock, 10);
fprintf(logfile,"CONNECT: MudDNS connected to port %d\n",SERVERPORT);
return(sock);
}
void new_conn(int mainfd) {
int fd, sin_len;
struct sockaddr_in sin;
struct hostent *h;
bzero ((char *) &sin, sizeof (struct sockaddr_in));
sin_len = sizeof (struct sockaddr_in);
if ((fd = accept (mainfd, (struct sockaddr *) &sin, &sin_len)) < 0) {
fprintf(logfile,"CONN: accept failed.\n");
return;
}
if (fcntl (fd, F_SETFL, FNDELAY) == -1) {
perror("fcntl()");
return;
}
h = gethostbyaddr((char *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
if (!h) {
FD_CLR(fd,&all_set);
close(fd);
return;
}
fprintf(logfile,"CONN: Connection from %s accepted\n",h->h_name);
FD_SET(fd,&all_set);
if (fd >= width)
width = fd + 1;
}
void read_request(int fd)
{ char line[19];
char outline[120];
char ip[16];
int plr;
char *res;
int num_read = read(fd,line,19);
unsigned long int inetnum;
struct hostent *h;
if (num_read < 1)
{ printf("Closing Connection.\n");
FD_CLR(fd,&all_set);
close(fd);
return;
}
sscanf(line,"%d:%s",&plr,ip);
if (plr < 0 || ip == NULL)
return;
#ifdef BUFFERDNS
else
{ res = trieSearch(ip);
if (res == NULL)
{ inetnum = inet_addr(ip);
h = gethostbyaddr((char *)&inetnum, sizeof(inetnum), AF_INET);
if (h)
{ res = (char *)h->h_name;
}
else
res = ip;
insertTrie(ip,res);
}
sprintf(outline,"%d:%s ",plr,res);
outline[strlen(outline)] = '\0';
write(fd,outline,120);
}
#else
else
{
inetnum = inet_addr(ip);
h = gethostbyaddr((char *)&inetnum, sizeof(inetnum), AF_INET);
if (h)
res = (char *)h->h_name;
else
res = ip;
sprintf(outline,"%d:%s ",plr,res);
outline[strlen(outline)] = '\0';
write(fd,outline,120);
}
#endif
}
void term_handler(int sig)
{ fprintf(logfile,"END: End session.\n");
fclose(logfile);
exit(0);
}
void set_sighandlers(void)
{ signal(SIGALRM,SIG_IGN);
signal(SIGABRT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGHUP,SIG_IGN);
signal(SIGTERM,term_handler);
}
int daemonize(void)
{ int pid;
set_sighandlers();
switch((pid = fork())) {
case 0 : break;
case -1: perror("Deamonize()"); return -1;
default:
fflush(stdout);
fflush(stderr);
exit(0); /* Die silently */
}
return 0;
}
void openLog(void)
{ logfile=fopen(DATA_DIR"/LOGS/muddns.log","a");
}