Mercurial > dnsbl
diff src/dnsbl.cpp @ 60:390ed250c5d2 stable-4-1
use local unix domain socket for resolver process communication
author | carl |
---|---|
date | Thu, 06 Jan 2005 11:35:38 -0800 |
parents | 510a511ad554 |
children | 7f44a4974bf6 |
line wrap: on
line diff
--- a/src/dnsbl.cpp Mon Jan 03 18:35:50 2005 -0800 +++ b/src/dnsbl.cpp Thu Jan 06 11:35:38 2005 -0800 @@ -201,7 +201,7 @@ static std::set<int> fd_pool; static int NULL_SOCKET = -1; -static int resolver_port = 0; // global port number to talk to the dns resolver process +static char *resolver_port = NULL; // unix domain socket to talk to the dns resolver process static int resolver_socket = NULL_SOCKET; // socket used to listen for resolver requests static time_t ERROR_SOCKET_TIME = 60; // number of seconds between attempts to open the spam filter socket static time_t last_error_time; @@ -305,13 +305,11 @@ // nothing recent, maybe this time it will work int sock = NULL_SOCKET; - hostent *host = gethostbyname("localhost"); - if (host) { - sockaddr_in server; - server.sin_family = host->h_addrtype; - server.sin_port = htons(resolver_port); - memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length); - sock = socket(PF_INET, SOCK_STREAM, 0); + sockaddr_un server; + memset(&server, '\0', sizeof(server)); + server.sun_family = AF_UNIX; + strncpy(server.sun_path, resolver_port, sizeof(server.sun_path)-1); + sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock != NULL_SOCKET) { bool rc = (connect(sock, (sockaddr *)&server, sizeof(server)) == 0); if (!rc) { @@ -322,7 +320,6 @@ } } else last_error_time = now; - } return sock; } @@ -637,7 +634,7 @@ } else { // peer closed the socket - //my_syslog("child worker process, peer closed socket while reading question"); + //my_syslog("!!child worker process, peer closed socket while reading question"); shutdown(socket, SHUT_RDWR); close(socket); return; @@ -646,7 +643,7 @@ // find the answer //char text[1000]; - //snprintf(text, sizeof(text), "child worker process has a question %s", question); + //snprintf(text, sizeof(text), "!!child worker process has a question %s", question); //my_syslog(text); glom.length = res_search(question, ns_c_in, ns_t_a, glom.answer, sizeof(glom.answer)); if (glom.length < 0) glom.length = 0; // represent all errors as zero length answers @@ -654,7 +651,7 @@ // write the answer char *buf = (char *)&glom; int len = glom.length + sizeof(glom.length); - //snprintf(text, sizeof(text), "child worker process writing answer length %d for total %d", glom.length, len); + //snprintf(text, sizeof(text), "!!child worker process writing answer length %d for total %d", glom.length, len); //my_syslog(text); int ws = 0; while (len > ws) { @@ -664,7 +661,7 @@ } else { // peer closed the socket! - //my_syslog("child worker process, peer closed socket while writing answer"); + //my_syslog("!!child worker process, peer closed socket while writing answer"); shutdown(socket, SHUT_RDWR); close(socket); return; @@ -695,9 +692,9 @@ char *buf = (char *)&glom; priv.my_read(buf, sizeof(glom.length)); buf += sizeof(glom.length); - //char text[1000]; - //snprintf(text, sizeof(text), "milter thread wrote question %s and has answer length %d", question, glom.length); - //my_syslog(text); + ///char text[1000]; + ///snprintf(text, sizeof(text), "!!milter thread wrote question %s and has answer length %d", question, glom.length); + ///my_syslog(text); if ((glom.length < 0) || (glom.length > sizeof(glom.answer))) { priv.err = true; return 0; // cannot process overlarge answers @@ -1609,6 +1606,7 @@ { fprintf(stderr, "Usage: %s [-d] [-c] -r port -p sm-sock-addr [-t timeout]\n", prog); fprintf(stderr, "where port is for the connection to our own dns resolver processes\n"); + fprintf(stderr, " and should be local-domain-socket-file-name\n"); fprintf(stderr, "where sm-sock-addr is for the connection to sendmail\n"); fprintf(stderr, " and should be one of\n"); fprintf(stderr, " inet:port@ip-address\n"); @@ -1649,7 +1647,8 @@ fprintf(stderr, "Illegal resolver socket: %s\n", optarg); exit(EX_USAGE); } - resolver_port = atoi(optarg); + resolver_port = strdup(optarg); + setup_socket(resolver_port); setreso = true; break; @@ -1749,6 +1748,17 @@ pthread_mutex_init(&resolve_mutex, 0); pthread_mutex_init(&fd_pool_mutex, 0); + // drop root privs + struct passwd *pw = getpwnam("dnsbl"); + if (pw) { + if (setgid(pw->pw_gid) == -1) { + my_syslog("failed to switch to group dnsbl"); + } + if (setuid(pw->pw_uid) == -1) { + my_syslog("failed to switch to user dnsbl"); + } + } + #ifdef NS_PACKETSZ // fork off the resolver listener process pid_t child = fork(); @@ -1758,22 +1768,22 @@ } if (child == 0) { // we are the child - dns resolver listener process - resolver_socket = socket(PF_INET, SOCK_STREAM, 0); + resolver_socket = socket(AF_UNIX, SOCK_STREAM, 0); if (resolver_socket < 0) { my_syslog("child failed to create resolver socket"); exit(0); // failed } - sockaddr_in server; - server.sin_family = AF_INET; - server.sin_port = htons(resolver_port); - server.sin_addr.s_addr = 0; + sockaddr_un server; + memset(&server, '\0', sizeof(server)); + server.sun_family = AF_UNIX; + strncpy(server.sun_path, resolver_port, sizeof(server.sun_path)-1); // set the socket options - int reuse_addr = 1; - linger linger_opt; - linger_opt.l_onoff = 0; // off - linger_opt.l_linger = 0; - setsockopt(resolver_socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&reuse_addr), sizeof(reuse_addr)); - setsockopt(resolver_socket, SOL_SOCKET, SO_LINGER, reinterpret_cast<char*>(&linger_opt), sizeof(linger_opt)); + ///int reuse_addr = 1; + ///linger linger_opt; + ///linger_opt.l_onoff = 0; // off + ///linger_opt.l_linger = 0; + ///setsockopt(resolver_socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&reuse_addr), sizeof(reuse_addr)); + ///setsockopt(resolver_socket, SOL_SOCKET, SO_LINGER, reinterpret_cast<char*>(&linger_opt), sizeof(linger_opt)); ///// set nonblocking mode ///int dummy = 0; ///int flags = fcntl(resolver_socket, F_GETFL, dummy); @@ -1793,29 +1803,10 @@ shutdown(resolver_socket, SHUT_RDWR); close(resolver_socket); my_syslog("child failed to listen to the resolver socket"); - return -1; - } - } - else { - sleep(2); // allow child to get started + exit(0); // failed } -#endif - - // drop root privs - struct passwd *pw = getpwnam("dnsbl"); - if (pw) { - if (setgid(pw->pw_gid) == -1) { - my_syslog("failed to switch to group dnsbl"); - } - if (setuid(pw->pw_uid) == -1) { - my_syslog("failed to switch to user dnsbl"); - } - } - -#ifdef NS_PACKETSZ - if (child == 0) { while (true) { - sockaddr_in client; + sockaddr_un client; socklen_t clientlen = sizeof(client); int s = accept(resolver_socket, (sockaddr *)&client, &clientlen); if (s > 0) { @@ -1824,15 +1815,25 @@ int newchild = fork(); if (newchild == 0) { // this is the worker process + // child does not need the listening socket + close(resolver_socket); my_syslog("child forked a worker process"); process_resolver_requests(s); my_syslog("child terminated a worker process"); exit(0); } + else { + // this is the parent + // parent does not need the accepted socket + close(s); + } } } exit(0); // make sure we don't fall thru. } + else { + sleep(2); // allow child to get started + } #endif // load the initial config