]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dynlistener.cc
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 PowerDNS.COM BV
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // $Id: dynlistener.cc,v 1.1 2002/11/27 15:18:33 ahu Exp $
20 /* (C) Copyright 2002 PowerDNS.COM BV */
24 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
35 #include <sys/types.h>
44 #include "arguments.hh"
45 #include "dnsbackend.hh"
46 #include "dynlistener.hh"
47 #include "dnspacket.hh"
55 DynListener::DynListener(const string
&pname
)
58 string programname
=pname
;
60 if(!programname
.empty()) {
61 struct sockaddr_un local
;
62 d_s
=socket(AF_UNIX
,SOCK_DGRAM
,0);
65 L
<<Logger::Error
<<"creating socket for dynlistener: "<<strerror(errno
)<<endl
;;
70 if(setsockopt(d_s
,SOL_SOCKET
,SO_REUSEADDR
,(char*)&tmp
,sizeof tmp
)<0)
71 throw AhuException(string("Setsockopt failed: ")+strerror(errno
));
73 string socketname
=arg()["socket-dir"]+"/";
74 cleanSlashes(socketname
);
76 if(!mkdir(socketname
.c_str(),0700)) // make /var directory, if needed
77 L
<<Logger::Warning
<<"Created local state directory '"<<socketname
<<"'"<<endl
;
78 else if(errno
!=EEXIST
) {
79 L
<<Logger::Critical
<<"FATAL: Unable to create socket directory ("<<socketname
<<") and it does not exist yet"<<endl
;
83 socketname
+=programname
+".controlsocket";
84 unlink(socketname
.c_str());
85 memset(&local
,0,sizeof(local
));
86 local
.sun_family
=AF_UNIX
;
87 strcpy(local
.sun_path
,socketname
.c_str());
89 if(bind(d_s
, (sockaddr
*)&local
,sizeof(local
))<0) {
90 L
<<Logger::Critical
<<"binding to dynlistener '"<<socketname
<<"': "<<strerror(errno
)<<endl
;
94 if(!arg()["setgid"].empty()) {
95 if(chown(socketname
.c_str(),static_cast<uid_t
>(-1),Utility::makeGidNumeric(arg()["setgid"]))<0)
96 L
<<Logger::Error
<<"Unable to change group ownership of controlsocket: "<<strerror(errno
)<<endl
;
97 if(chmod(socketname
.c_str(),0660)<0)
98 L
<<Logger::Error
<<"Unable to change group access mode of controlsocket: "<<strerror(errno
)<<endl
;
102 L
<<Logger::Warning
<<"Listening on controlsocket in '"<<socketname
<<"'"<<endl
;
111 void DynListener::go()
114 pthread_create(&d_tid
,0,&DynListener::theListenerHelper
,this);
117 void *DynListener::theListenerHelper(void *p
)
119 DynListener
*us
=static_cast<DynListener
*>(p
);
124 string
DynListener::getLine()
127 memset(mesg
,0,sizeof(mesg
));
131 d_addrlen
=sizeof(d_remote
);
133 if((len
=recvfrom(d_s
,mesg
,512,0,(sockaddr
*) &d_remote
, &d_addrlen
))<0) {
134 L
<<Logger::Error
<<"Unable to receive packet from controlsocket ("<<d_s
<<") - exiting: "<<strerror(errno
)<<endl
;
141 if((len
=read(0,mesg
,512))<0)
142 throw AhuException("Reading from the control pipe: "+stringerror());
144 throw AhuException("Guardian exited - going down as well");
150 void DynListener::sendLine(const string
&l
)
153 sendto(d_s
,l
.c_str(),l
.length()+1,0,(struct sockaddr
*)&d_remote
,d_addrlen
);
157 write(1,line
.c_str(),line
.length());
161 void DynListener::registerFunc(const string
&name
, g_funk_t
*gf
)
166 void DynListener::registerRestFunc(g_funk_t
*gf
)
171 void DynListener::theListener()
174 map
<string
,string
> parameters
;
177 string line
=getLine();
181 stringtok(parts
,line
," ");
183 sendLine("Empty line");
187 if(!d_funcdb
[parts
[0]]) {
189 sendLine((*d_restfunc
)(parts
,d_ppid
));
191 sendLine("Unknown command: '"+parts
[0]+"'");
195 sendLine((*d_funcdb
[parts
[0]])(parts
,d_ppid
));
198 catch(AhuException
&AE
)
200 L
<<Logger::Error
<<"Fatal: "<<AE
.reason
<<endl
;
204 L
<<Logger::Error
<<"Fatal: "<<E
<<endl
;
208 L
<<Logger::Error
<<"Fatal: unknown exception occured"<<endl
;