/*------------------------------------------------------------------------*/ void HandleSigHup() /*------------------------------------------------------------------------*/ { /* Reinitialize */ SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon reset by SIGHUP\n"); SLPDLog("****************************************\n\n"); /* unregister with all DAs */ SLPDKnownDADeinit(); /* re-read properties */ SLPDPropertyInit(G_SlpdCommandLine.cfgfile); #ifdef ENABLE_SECURITY /* Re-initialize SPI stuff*/ SLPDSpiInit(G_SlpdCommandLine.spifile); #endif /* Re-read the static registration file (slp.reg)*/ SLPDDatabaseReInit(G_SlpdCommandLine.regfile); /* Rebuild Known DA database */ SLPDKnownDAInit(); SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon reset finished\n"); SLPDLog("****************************************\n\n"); }
/*------------------------------------------------------------------------*/ void HandleSigTerm() /*------------------------------------------------------------------------*/ { struct timeval timeout; fd_set readfds; fd_set writefds; int highfd = 0; int fdcount = 0; SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon shutting down\n"); SLPDLog("****************************************\n"); /* close all incoming sockets */ SLPDIncomingDeinit(); /* unregister with all DAs */ SLPDKnownDADeinit(); timeout.tv_sec = 5; timeout.tv_usec = 0; /* Do a dead DA passive advert to tell everyone we're goin' down */ SLPDKnownDAPassiveDAAdvert(0, 1); /* if possible wait until all outgoing socket are done and closed */ while(SLPDOutgoingDeinit(1)) { FD_ZERO(&writefds); FD_ZERO(&readfds); LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); fdcount = select(highfd+1,&readfds,&writefds,0,&timeout); if(fdcount == 0) { break; } SLPDOutgoingHandler(&fdcount,&readfds,&writefds); } SLPDOutgoingDeinit(0); SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon shut down\n"); SLPDLog("****************************************\n"); #ifdef DEBUG #ifdef ENABLE_SECURITY SLPDSpiDeinit(); #endif SLPDDatabaseDeinit(); SLPDPropertyDeinit(); xmalloc_deinit(); #endif }
/*=========================================================================*/ void SLPDLogRegistration(const char* prefix, SLPDatabaseEntry* entry) /* Log record of having added a registration to the database. Logging of */ /* registraions will only occur if registration trace is enabled */ /* G_SlpProperty.traceReg != 0 */ /* */ /* prefix (IN) an informative prefix for the log entry */ /* */ /* entry (IN) the database entry that was affected */ /* */ /* Returns: none */ /*=========================================================================*/ { char addr_str[INET6_ADDRSTRLEN]; if (prefix == NULL || entry == NULL) { return; } if (G_SlpdProperty.traceReg) { SLPDLog("\n"); SLPDLogTime(); SLPDLog("DATABASE - %s:\n",prefix); SLPDLog(" SA address = "); switch (entry->msg->body.srvreg.source) { case SLP_REG_SOURCE_UNKNOWN: SLPDLog("<unknown>\n"); break; case SLP_REG_SOURCE_REMOTE: SLPDLog("remote (%s)\n", SLPNetSockAddrStorageToString(&(entry->msg->peer), addr_str, sizeof(addr_str))); break; case SLP_REG_SOURCE_LOCAL: SLPDLog("IPC (libslp)\n"); break; case SLP_REG_SOURCE_STATIC: SLPDLog("static (slp.reg)\n"); break; } SLPDLogBuffer(" service-url = ", entry->msg->body.srvreg.urlentry.urllen, entry->msg->body.srvreg.urlentry.url); SLPDLogBuffer(" scope = ", entry->msg->body.srvreg.scopelistlen, entry->msg->body.srvreg.scopelist); SLPDLogBuffer(" attributes = ", entry->msg->body.srvreg.attrlistlen, entry->msg->body.srvreg.attrlist); } }
/*=========================================================================*/ void SLPDLogDAAdvertisement(const char* prefix, SLPDatabaseEntry* entry) /* Log record of addition or removal of a DA to the store of known DAs. */ /* Will only occur if DA Advertisment message logging is enabled */ /* G_SlpProperty.traceDATraffic != 0 */ /* */ /* prefix (IN) an informative prefix for the log entry */ /* */ /* entry (IN) the database entry that was affected */ /* */ /* Returns: none */ /*=========================================================================*/ { char addr_str[INET6_ADDRSTRLEN]; if (prefix == NULL || entry == NULL) { return; } if (G_SlpdProperty.traceDATraffic) { SLPDLog("\n"); SLPDLogTime(); SLPDLog("KNOWNDA - %s:\n",prefix); SLPDLog(" DA address = %s\n",SLPNetSockAddrStorageToString(&(entry->msg->peer), addr_str, sizeof(addr_str))); SLPDLogBuffer(" directory-agent-url = ", entry->msg->body.daadvert.urllen, entry->msg->body.daadvert.url); SLPDLog(" bootstamp = %x\n",entry->msg->body.daadvert.bootstamp); SLPDLogBuffer(" scope = ", entry->msg->body.daadvert.scopelistlen, entry->msg->body.daadvert.scopelist); SLPDLogBuffer(" attributes = ", entry->msg->body.daadvert.attrlistlen, entry->msg->body.daadvert.attrlist); #ifdef ENABLE_SLPV2_SECURITY SLPDLogBuffer(" SPI list = ", entry->msg->body.daadvert.spilistlen, entry->msg->body.daadvert.spilist); #endif /*ENABLE_SLPV2_SECURITY*/ } }
/*=========================================================================*/ void SLPDLogParseWarning(struct sockaddr_storage* peeraddr, SLPBuffer buf) /* Log a parsing error warning and dumps the invalid message. */ /*=========================================================================*/ { unsigned char* curpos; int i = 0; if (peeraddr == NULL || buf == NULL) { return; } SLPDLog("\n"); SLPDLogTime(); SLPDLog("*** WARNING Parse Error ***\n"); SLPDLogPeerAddr(peeraddr); SLPDLog("message size = %i\n",buf->end - buf->start); SLPDLog("message dump follows:\n"); for (curpos = buf->start; curpos < buf->end; curpos++) { SLPDLog("0x%02x",*curpos); if (*curpos < 0x20 || *curpos > 0x7f) { SLPDLog("(' ') "); } else { SLPDLog("('%c') ",*curpos); } /* newline every 70 columns */ i++; if (i==10) { i=0; SLPDLog("\n"); } } SLPDLog("\n"); }
/*=========================================================================*/ void SLPDLogMessage(int msglogflags, struct sockaddr_storage* peerinfo, struct sockaddr_storage* localaddr, SLPBuffer buf) /* Log record of receiving or sending an SLP Message. Logging will only */ /* occur if message logging is enabled G_SlpProperty.traceMsg != 0 */ /* */ /* msglogflags (IN) What type of message to log */ /* */ /* peerinfo (IN) the source or destination peer */ /* */ /* peerinfo (IN) the local address */ /* */ /* msg (IN) the message to log */ /* */ /* Returns: none */ /*=========================================================================*/ { SLPMessage msg; char addr_str[INET6_ADDRSTRLEN]; if (peerinfo == NULL || buf == NULL) { return; } if ((G_SlpdProperty.traceMsg && (msglogflags & SLPDLOG_TRACEMSG)) || (G_SlpdProperty.traceDrop && (msglogflags & SLPDLOG_TRACEDROP)) ) { /* Don't log localhost traffic since it is probably IPC */ /* and don't log empty messages */ if (!SLPNetIsLocal(peerinfo) && buf->end != buf->start) { msg = SLPMessageAlloc(); if (msg) { SLPDLog("\n"); SLPDLogTime(); SLPDLog("MESSAGE - "); if (msglogflags == SLPDLOG_TRACEMSG_OUT) { SLPDLog("Trace message (OUT)\n"); } else if (msglogflags == SLPDLOG_TRACEMSG_IN) { SLPDLog("Trace message (IN)\n"); } else if (msglogflags == SLPDLOG_TRACEDROP) { SLPDLog("Dropped message (following message silently ignored)\n"); } else { SLPDLog("\n"); } if (SLPMessageParseBuffer(peerinfo,localaddr,buf,msg) == 0) { SLPDLogMessageInternals(msg); } else { SLPDLog("Message parsing failed\n"); SLPDLog("Peer: \n"); SLPDLog(" IP address: %s\n", SLPNetSockAddrStorageToString(&(msg->peer), addr_str, sizeof(addr_str))); } SLPMessageFree(msg); } } } }
/*=========================================================================*/ int main(int argc, char* argv[]) /*=========================================================================*/ { fd_set readfds; fd_set writefds; int highfd; int fdcount = 0; #ifdef DEBUG xmalloc_init("/var/log/slpd_xmalloc.log",0); #endif /*------------------------*/ /* Parse the command line */ /*------------------------*/ if(SLPDParseCommandLine(argc,argv)) { SLPDFatal("Invalid command line\n"); } /*------------------------------*/ /* Make sure we are root */ /*------------------------------*/ if(getuid() != 0) { SLPDFatal("slpd must be started by root\n"); } /*--------------------------------------*/ /* Make sure we are not already running */ /*--------------------------------------*/ if(CheckPid(G_SlpdCommandLine.pidfile)) { SLPDFatal("slpd is already running. Check %s\n", G_SlpdCommandLine.pidfile); } /*------------------------------*/ /* Initialize the log file */ /*------------------------------*/ if(SLPDLogFileOpen(G_SlpdCommandLine.logfile, 1)) { SLPDFatal("Could not open logfile %s\n",G_SlpdCommandLine.logfile); } /*------------------------*/ /* Seed the XID generator */ /*------------------------*/ SLPXidSeed(); /*---------------------*/ /* Log startup message */ /*---------------------*/ SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon started\n"); SLPDLog("****************************************\n"); SLPDLog("Command line = %s\n",argv[0]); SLPDLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile); SLPDLog("Using registration file = %s\n",G_SlpdCommandLine.regfile); #ifdef ENABLE_SECURITY SLPDLog("Using SPI file = %s\n",G_SlpdCommandLine.spifile); #endif /*--------------------------------------------------*/ /* Initialize for the first time */ /*--------------------------------------------------*/ if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) || #ifdef ENABLE_SECURITY SLPDSpiInit(G_SlpdCommandLine.spifile) || #endif SLPDDatabaseInit(G_SlpdCommandLine.regfile) || SLPDIncomingInit() || SLPDOutgoingInit() || SLPDKnownDAInit()) { SLPDFatal("slpd initialization failed\n"); } SLPDLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces); SLPDLog("Agent URL = %s\n",G_SlpdProperty.myUrl); /*---------------------------*/ /* make slpd run as a daemon */ /*---------------------------*/ if(Daemonize(G_SlpdCommandLine.pidfile)) { SLPDFatal("Could not daemonize\n"); } /*-----------------------*/ /* Setup signal handlers */ /*-----------------------*/ if(SetUpSignalHandlers()) { SLPDFatal("Error setting up signal handlers.\n"); } /*------------------------------*/ /* Set up alarm to age database */ /*------------------------------*/ alarm(SLPD_AGE_INTERVAL); /*-----------*/ /* Main loop */ /*-----------*/ SLPDLog("Startup complete entering main run loop ...\n\n"); G_SIGALRM = 0; G_SIGTERM = 0; G_SIGHUP = 0; #ifdef DEBUG G_SIGINT = 0; #endif while(G_SIGTERM == 0) { /*--------------------------------------------------------*/ /* Load the fdsets up with all valid sockets in the list */ /*--------------------------------------------------------*/ highfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds); LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); /*--------------------------------------------------*/ /* Before select(), check to see if we got a signal */ /*--------------------------------------------------*/ if(G_SIGALRM || G_SIGHUP) { goto HANDLE_SIGNAL; } /*-------------*/ /* Main select */ /*-------------*/ fdcount = select(highfd+1,&readfds,&writefds,0,0); if(fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */ { SLPDIncomingHandler(&fdcount,&readfds,&writefds); SLPDOutgoingHandler(&fdcount,&readfds,&writefds); } /*----------------*/ /* Handle signals */ /*----------------*/ HANDLE_SIGNAL: if(G_SIGHUP) { HandleSigHup(); G_SIGHUP = 0; } if(G_SIGALRM) { HandleSigAlrm(); G_SIGALRM = 0; alarm(SLPD_AGE_INTERVAL); } #ifdef DEBUG if (G_SIGINT) { HandleSigInt(); G_SIGINT = 0; } #endif } /* End of main loop */ /* Got SIGTERM */ HandleSigTerm(); return 0; }
/** Process main entry point. * * @param[in] argc - The number of command line arguments passed in @p argv. * @param[in] argv - An array of pointers to command line arguments. * * @return Zero on success, or a non-zero shell error code. * * @remarks This routine contains the main server loop. */ int main(int argc, char * argv[]) { fd_set readfds; fd_set writefds; int highfd; int fdcount = 0; time_t curtime; struct timeval timeout; #ifdef DEBUG xmalloc_init("/var/log/slpd_xmalloc.log", 0); #endif /* Parse the command line */ if (SLPDParseCommandLine(argc,argv)) SLPDFatal("Invalid command line\n"); /* make sure we are root */ if (getuid() != 0) SLPDFatal("slpd must be started by root\n"); /* make sure we are not already running */ if (CheckPid(G_SlpdCommandLine.pidfile)) SLPDFatal("slpd is already running. Check %s\n", G_SlpdCommandLine.pidfile); /* Initialize the preferences so we know if the log file is to be overwritten or appended.*/ if (SLPDPropertyInit(G_SlpdCommandLine.cfgfile)) SLPDFatal("slpd initialization failed during property load\n"); /* make slpd run as a daemon */ if (Daemonize(G_SlpdCommandLine.pidfile)) SLPDFatal("Could not daemonize\n"); /* initialize the log file */ if (SLPDLogFileOpen(G_SlpdCommandLine.logfile, G_SlpdProperty.appendLog)) SLPDFatal("Could not open logfile %s\n",G_SlpdCommandLine.logfile); /* seed the XID generator */ SLPXidSeed(); /* log startup message */ SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon started\n"); SLPDLog("****************************************\n"); SLPDLog("Command line = %s\n", argv[0]); SLPDLog("Using configuration file = %s\n", G_SlpdCommandLine.cfgfile); SLPDLog("Using registration file = %s\n", G_SlpdCommandLine.regfile); #ifdef ENABLE_SLPv2_SECURITY SLPDLog("Using SPI file = %s\n", G_SlpdCommandLine.spifile); #endif /* initialize for the first time */ SLPDPropertyReinit(); /*So we get any property-related log messages*/ if ( #ifdef ENABLE_SLPv2_SECURITY SLPDSpiInit(G_SlpdCommandLine.spifile) || #endif SLPDDatabaseInit(G_SlpdCommandLine.regfile) || SLPDIncomingInit() || SLPDOutgoingInit() || SLPDKnownDAInit()) SLPDFatal("slpd initialization failed\n"); SLPDLog("Agent Interfaces = %s\n", G_SlpdProperty.interfaces); if (G_SlpdProperty.port != SLP_RESERVED_PORT) SLPDLog("Using port %d instead of default %d\n", G_SlpdProperty.port, SLP_RESERVED_PORT); /* drop privileges to reduce security risk */ if (DropPrivileges()) SLPDFatal("Could not drop privileges\n"); /* Setup signal handlers */ if (SetUpSignalHandlers()) SLPDFatal("Error setting up signal handlers.\n"); /* Set up alarm to age database -- a shorter start, so SAs register with us quickly on our startup */ alarm(2); /* Main loop */ SLPDLog("Startup complete entering main run loop ...\n\n"); G_SIGALRM = 0; G_SIGTERM = 0; G_SIGHUP = 0; #ifdef DEBUG G_SIGINT = 0; G_SIGUSR1 = 0; #endif while (G_SIGTERM == 0) { /* load the fdsets up with all valid sockets in the list */ highfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); LoadFdSets(&G_IncomingSocketList, &highfd, &readfds, &writefds); LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds, &writefds); /* before select(), check to see if we got a signal */ if (G_SIGALRM || G_SIGHUP) goto HANDLE_SIGNAL; /* main select -- we time out every second so the outgoing retries can occur*/ time(&curtime); timeout.tv_sec = 1; timeout.tv_usec = 0; fdcount = select(highfd + 1, &readfds, &writefds, 0, &timeout); if (fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */ { SLPDIncomingHandler(&fdcount, &readfds, &writefds); SLPDOutgoingHandler(&fdcount, &readfds, &writefds); SLPDOutgoingRetry(time(0) - curtime); } else if (fdcount == 0) SLPDOutgoingRetry(time(0) - curtime); HANDLE_SIGNAL: if (G_SIGHUP) { HandleSigHup(); G_SIGHUP = 0; } if (G_SIGALRM) { HandleSigAlrm(); G_SIGALRM = 0; alarm(SLPD_AGE_INTERVAL); } #ifdef DEBUG if (G_SIGINT) { HandleSigInt(); G_SIGINT = 0; } if (G_SIGUSR1) { HandleSigUsr1(); G_SIGUSR1 = 0; } #endif } /* End of main loop */ /* Got SIGTERM */ HandleSigTerm(); return 0; }
/*--------------------------------------------------------------------------*/ void ServiceStart (int argc, char **argv) /*--------------------------------------------------------------------------*/ { fd_set readfds; fd_set writefds; int highfd; int fdcount = 0; time_t curtime; time_t alarmtime; struct timeval timeout; WSADATA wsaData; WORD wVersionRequested = MAKEWORD(1,1); /*------------------------*/ /* Service initialization */ /*------------------------*/ if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state*/ NO_ERROR, /* exit code */ 3000)) /* wait hint */ { goto cleanup; } if(WSAStartup(wVersionRequested, &wsaData) != 0) { (void)ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); goto cleanup; } /*------------------------*/ /* Parse the command line */ /*------------------------*/ if(SLPDParseCommandLine(argc,argv)) { ReportStatusToSCMgr(SERVICE_STOP_PENDING, /* service state */ NO_ERROR, /* exit code */ 0); /* wait hint */ goto cleanup_winsock; } if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state */ NO_ERROR, /* exit code */ 3000)) /* wait hint */ { goto cleanup_winsock; } /*------------------------------*/ /* Initialize the log file */ /*------------------------------*/ if(SLPDLogFileOpen(G_SlpdCommandLine.logfile, 1)) { SLPDLog("Could not open logfile %s\n",G_SlpdCommandLine.logfile); goto cleanup_winsock; } /*------------------------*/ /* Seed the XID generator */ /*------------------------*/ SLPXidSeed(); /*---------------------*/ /* Log startup message */ /*---------------------*/ SLPDLog("****************************************\n"); SLPDLogTime(); SLPDLog("SLPD daemon started\n"); SLPDLog("****************************************\n"); SLPDLog("Command line = %s\n",argv[0]); SLPDLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile); SLPDLog("Using registration file = %s\n",G_SlpdCommandLine.regfile); if(!ReportStatusToSCMgr(SERVICE_START_PENDING, /* service state */ NO_ERROR, /* exit code */ 3000)) /* wait hint */ { goto cleanup_winsock; } /*--------------------------------------------------*/ /* Initialize for the first time */ /*--------------------------------------------------*/ if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) || SLPDDatabaseInit(G_SlpdCommandLine.regfile) || SLPDIncomingInit() || SLPDOutgoingInit() || SLPDKnownDAInit()) { SLPDLog("slpd initialization failed\n"); goto cleanup_winsock; } SLPDLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces); /* Service is now running, perform work until shutdown */ if(!ReportStatusToSCMgr(SERVICE_RUNNING, /* service state */ NO_ERROR, /* exit code */ 0)) /* wait hint */ { goto cleanup_winsock; } /*-----------*/ /* Main loop */ /*-----------*/ SLPDLog("Startup complete entering main run loop ...\n\n"); G_SIGTERM = 0; curtime = time(&alarmtime); alarmtime = curtime + SLPD_AGE_INTERVAL; while(G_SIGTERM == 0) { /*--------------------------------------------------------*/ /* Load the fdsets up with all valid sockets in the list */ /*--------------------------------------------------------*/ highfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds); LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); /*--------------------------------------------------*/ /* Before select(), check to see if we got a signal */ /*--------------------------------------------------*/ if(G_SIGALRM) { goto HANDLE_SIGNAL; } /*-------------*/ /* Main select */ /*-------------*/ timeout.tv_sec = SLPD_AGE_INTERVAL; timeout.tv_usec = 0; fdcount = select(highfd+1,&readfds,&writefds,0,&timeout); if(fdcount > 0) /* fdcount will be < 0 when timed out */ { SLPDIncomingHandler(&fdcount,&readfds,&writefds); SLPDOutgoingHandler(&fdcount,&readfds,&writefds); } /*----------------*/ /* Handle signals */ /*----------------*/ HANDLE_SIGNAL: curtime = time(&curtime); if(curtime >= alarmtime) { HandleSigAlrm(); alarmtime = curtime + SLPD_AGE_INTERVAL; } } /* End of main loop */ /* Got SIGTERM */ HandleSigTerm(); cleanup_winsock: WSACleanup(); cleanup: ; }