/****************************************************************************** ** 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"); }