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"
306 #if defined(__clang__) && __clang_major__ >= 19
307 # pragma clang diagnostic push
308 # pragma clang diagnostic ignored "-Wcast-function-type-mismatch"
311 clnt_stat ret = clnt_call(
client, NULLPROC, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, NULL,
timeout);
312 #if defined(__clang__) && __clang_major__ >= 19
313 # pragma clang diagnostic pop
316 # pragma GCC diagnostic pop
318 if (ret == RPC_SUCCESS){
320 ServerSvc->
Message(MSG::ERROR,
"Server exists and is alive on local host - stopping this thread");
322 }
else ServerSvc->
Message(MSG::WARNING,
"Existing server does not respond");
323 }
else ServerSvc->
Message(MSG::WARNING,
"Can not create client for existing server");
326 ServerSvc->
Message(MSG::WARNING,
"Clearing existing portmap entry!");
336 if ((rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) &&
337 (rpc_createerr.cf_stat != RPC_SYSTEMERROR )){
338 ServerSvc->
Message(MSG::ERROR,clnt_spcreateerror(
"Failed querying portmapper on local host for existing servers"));
343 int server_socket = RPC_ANYSOCK;
346 if (PortNumber != 0){
349 if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) != 0) {
350 checkResult(errno,
"server thread creating socket",ServerSvc);
355 struct sockaddr_in server_addr;
356 server_addr.sin_family = AF_INET;
357 server_addr.sin_addr.s_addr = INADDR_ANY;
358 server_addr.sin_port = htons(PortNumber);
359 memset(&server_addr.sin_zero, 0,
sizeof(server_addr.sin_zero));
362 if (bind(server_socket, (
struct sockaddr *)&server_addr,
sizeof(
struct sockaddr)) != 0){
363 std::ostringstream
msg;
msg <<
"server thread binding socket to port " << PortNumber;
367 std::ostringstream
msg;
msg <<
"Successfully bound port " << PortNumber;
372 SVCXPRT * transp = svctcp_create(server_socket, 0, 0);
375 if (transp == NULL) {
376 ServerSvc->
Message(MSG::ERROR,
"Opening TCP socket failed");
386 ServerSvc->
Message(MSG::ERROR,
"Could not register ONCRPC Server with RPC daemon");
387 checkResult(errno,
"registering ONCRPC Server with RPC daemon",ServerSvc);
392 fd_set SocketFileDescriptorSet;
394 int NFileDescriptors = FD_SETSIZE;
397 unsigned long NRequests = 0;
404 SocketFileDescriptorSet = svc_fdset;
410 int ret =
select(NFileDescriptors,&SocketFileDescriptorSet,NULL,NULL,NULL);
416 if ( errno == EINTR ) continue ;
418 checkResult(errno,
"server thread returning from select",ServerSvc);
428 svc_getreqset(&SocketFileDescriptorSet);
447 ServerSvc->
Message(MSG::INFO,
" ... finished all dispatch threads");
455 unsigned long* NReqPtr =
new unsigned long(NRequests);
457 pthread_exit(NReqPtr);
460 std::ostringstream
msg;
msg <<
"Caught exception in ServerThread: " <<
e.what();