15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <sys/socket.h>
24 extern "C" void get_myaddress (
struct sockaddr_in *);
58 std::ostringstream
msg;
msg <<
"Created new dispatch thread " << pthread_self();
62 switch (rqstp->rq_proc){
77 ReturnEvent(rqstp->rq_xprt, eventRequest, ServerSvc);
84 std::ostringstream
msg;
85 msg <<
"Client request for server procedure #" << rqstp->rq_proc <<
" which is not defined";
87 svcerr_noproc(rqstp->rq_xprt);
102 std::ostringstream
msg;
msg <<
"Caught exception in DispatchThread: " <<
e.what();
120 std::ostringstream
msg;
msg <<
"Request handler in thread " << pthread_self();
129 auto caller = (
struct sockaddr* )svc_getcaller(rqstp->rq_xprt);
130 char port[NI_MAXSERV];
131 char host[NI_MAXHOST];
132 char IPAddr[INET6_ADDRSTRLEN];
135 msg <<
"Request from host ";
137 if(getnameinfo(caller, rqstp->rq_xprt->xp_addrlen,
143 if(getnameinfo(caller, rqstp->rq_xprt->xp_addrlen,
144 IPAddr,
sizeof IPAddr,
146 NI_NUMERICSERV | NI_NUMERICHOST) == 0)
147 msg <<
"(" << IPAddr <<
") on port " << port;
157 switch (rqstp->rq_proc){
168 if (!svc_getargs(rqstp->rq_xprt,(xdrproc_t)
xdr_event_req,(caddr_t)evtReq)){
169 checkResult(errno,
"creating dispatch tread arguments from GETEVENT call",ServerSvc);
171 svcerr_decode(rqstp->rq_xprt);
177 DpThreadArgs.
evtReq = evtReq;
186 evt->EventNumber=-2;
evt->RunNumber=-2;
evt->StreamName=NULL;
evt->NBytes=0;
evt->EventData=NULL;
189 if (!svc_getargs(rqstp->rq_xprt,(xdrproc_t)
xdr_event,(caddr_t)
evt)){
190 checkResult(errno,
"creating dispatch tread arguments from SETEVENT call",ServerSvc);
192 svcerr_decode(rqstp->rq_xprt);
207 pthread_attr_t attr; retVal = pthread_attr_init (&attr);
208 if ( !
checkResult(retVal,
"request handler initializing thread attributes",ServerSvc)) return ;
212 if ( !
checkResult(retVal,
"request handler setting thread stacksize",ServerSvc)) return ;
217 retVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
218 if ( !
checkResult(retVal,
"request handler setting thread detach state",ServerSvc))
return;
221 pthread_t dispatchThread;
223 if ( !
checkResult(retVal,
"request handler creating dispatch thread",ServerSvc))
return;
229 retVal = pthread_attr_destroy(&attr);
230 if ( !
checkResult(retVal,
"request handler destroying thread attributes",ServerSvc))
return;
233 std::ostringstream
msg;
msg <<
"Caught exception in RequestHandler: " <<
e.what();
267 if (!
checkResult(retVal,
"server thread creating thread-specific key",ServerSvc)) pthread_exit(NULL);
268 retVal = pthread_setspecific(ServerSvcKey, ServerSvc);
269 if (!
checkResult(retVal,
"server thread setting thread-specific key",ServerSvc)) pthread_exit(NULL);
276 ServerSvc->
Message(MSG::INFO,
"Started ONCRPC server thread");
280 ServerSvc->
Message(MSG::WARNING,
"The run server flag is not set - stopping server thread immediately");
289 struct sockaddr_in my_addr; get_myaddress(&my_addr);
296 <<
" already registered with portmapper on local host";
303 # pragma GCC diagnostic push
304 # pragma GCC diagnostic ignored "-Wcast-function-type"
307 clnt_stat ret = clnt_call(
client, NULLPROC, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, NULL,
timeout);
309 # pragma GCC diagnostic pop
311 if (ret == RPC_SUCCESS){
313 ServerSvc->
Message(MSG::ERROR,
"Server exists and is alive on local host - stopping this thread");
315 }
else ServerSvc->
Message(MSG::WARNING,
"Existing server does not respond");
316 }
else ServerSvc->
Message(MSG::WARNING,
"Can not create client for existing server");
319 ServerSvc->
Message(MSG::WARNING,
"Clearing existing portmap entry!");
329 if ((rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) &&
330 (rpc_createerr.cf_stat != RPC_SYSTEMERROR )){
331 ServerSvc->
Message(MSG::ERROR,clnt_spcreateerror(
"Failed querying portmapper on local host for existing servers"));
336 int server_socket = RPC_ANYSOCK;
339 if (PortNumber != 0){
342 if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) != 0) {
343 checkResult(errno,
"server thread creating socket",ServerSvc);
348 struct sockaddr_in server_addr;
349 server_addr.sin_family = AF_INET;
350 server_addr.sin_addr.s_addr = INADDR_ANY;
351 server_addr.sin_port = htons(PortNumber);
352 memset(&server_addr.sin_zero, 0,
sizeof(server_addr.sin_zero));
355 if (bind(server_socket, (
struct sockaddr *)&server_addr,
sizeof(
struct sockaddr)) != 0){
356 std::ostringstream
msg;
msg <<
"server thread binding socket to port " << PortNumber;
360 std::ostringstream
msg;
msg <<
"Successfully bound port " << PortNumber;
365 SVCXPRT * transp = svctcp_create(server_socket, 0, 0);
368 if (transp == NULL) {
369 ServerSvc->
Message(MSG::ERROR,
"Opening TCP socket failed");
379 ServerSvc->
Message(MSG::ERROR,
"Could not register ONCRPC Server with RPC daemon");
380 checkResult(errno,
"registering ONCRPC Server with RPC daemon",ServerSvc);
385 fd_set SocketFileDescriptorSet;
387 int NFileDescriptors = FD_SETSIZE;
390 unsigned long NRequests = 0;
397 SocketFileDescriptorSet = svc_fdset;
403 int ret =
select(NFileDescriptors,&SocketFileDescriptorSet,NULL,NULL,NULL);
409 if ( errno == EINTR ) continue ;
411 checkResult(errno,
"server thread returning from select",ServerSvc);
421 svc_getreqset(&SocketFileDescriptorSet);
440 ServerSvc->
Message(MSG::INFO,
" ... finished all dispatch threads");
448 unsigned long* NReqPtr =
new unsigned long(NRequests);
450 pthread_exit(NReqPtr);
453 std::ostringstream
msg;
msg <<
"Caught exception in ServerThread: " <<
e.what();