static void run_server(struct runtime_config *rtc) { struct sockaddr_in client_addr; socklen_t addr_len; pthread_attr_t attr; #ifdef USE_SYSTEMD int ret; ret = sd_listen_fds(0); if (1 < ret) faillog("no or too many file descriptors received"); else if (ret == 1) rtc->server_s = SD_LISTEN_FDS_START + 0; else { #endif if (!(rtc->server_s = socket(rtc->res->ai_family, rtc->res->ai_socktype, rtc->res->ai_protocol))) err(EXIT_FAILURE, "cannot create socket"); if (bind(rtc->server_s, rtc->res->ai_addr, rtc->res->ai_addrlen)) err(EXIT_FAILURE, "unable to bind"); if (listen(rtc->server_s, SOMAXCONN)) err(EXIT_FAILURE, "unable to listen"); #ifdef USE_SYSTEMD } #endif if (pthread_attr_init(&attr)) err(EXIT_FAILURE, "cannot init thread attribute"); if (pthread_rwlock_init(&(rtc->lock), NULL)) err(EXIT_FAILURE, "cannot init read-write lock"); daemonize(); if (rtc->msg_type == STATE_UNKNOWN) read_status_from_file(rtc); if (update_pid_file(rtc)) faillog("cannot write pid file"); openlog(PACKAGE_NAME, LOG_PID, LOG_DAEMON); signal(SIGHUP, stop_server); signal(SIGINT, stop_server); signal(SIGTERM, stop_server); #ifdef USE_SYSTEMD sd_journal_send("MESSAGE=service started", "MESSAGE_ID=%s", SD_ID128_CONST_STR(MESSAGE_STOP_START), "STATE=%s", state_messages[rtc->msg_type], "PRIORITY=6", NULL); #else syslog(LOG_INFO, "started in state %s", state_messages[rtc->msg_type]); #endif while (1) { int accepted; pthread_t thread; int *newsock; addr_len = sizeof(client_addr); accepted = accept(rtc->server_s, (struct sockaddr *)&client_addr, &addr_len); newsock = malloc(sizeof(int)); *newsock = accepted; pthread_create(&thread, NULL, handle_request, newsock); pthread_detach(thread); } }
void detach(void) { pid_t pid; sem_id = semget(IPC_PRIVATE, 1, 0666|IPC_CREAT|IPC_EXCL); if (sem_id == -1) { perror("semget"); exit(1); } if (semctl(sem_id, 0, SETVAL, 0) == -1) { perror("semctl"); if (semctl(sem_id, 0, IPC_RMID) == -1) perror("sem_id IPC_RMID"); exit(1); } pid = fork(); if (pid < 0) { perror("fork"); exit(1); } if (pid) { /* parent */ update_pid_file(pid); if (down(sem_id)) perror("down"); semctl(sem_id, 0, IPC_RMID); exit(0); } if (pid == 0) { /* child */ struct sigaction sa = { .sa_sigaction = sighandler, .sa_flags = SA_SIGINFO, }; /* * XXX: SIGKILL cannot be caught. * The parent will wait for ever if child is OOM killed. */ sigaction(SIGBUS, &sa, NULL); if (atexit(delete_pid_file) != 0) { fprintf(stderr, "cannot set exit function\n"); exit(1); } } }
static void catch_signals(int signal) { if (pthread_rwlock_wrlock(&rtc.lock)) { #ifdef USE_SYSTEMD sd_journal_send("MESSAGE=could not get lock", "MESSAGE_ID=%s", SD_ID128_CONST_STR(MESSAGE_ERROR), "STRERROR=%s", strerror(errno), "PRIORITY=3", NULL); #else syslog(LOG_ERR, "could not get lock"); #endif return; } switch (signal) { case SIGUSR1: rtc.msg_type = STATE_DISABLE; break; case SIGUSR2: rtc.msg_type = STATE_MAINTENANCE; break; case SIGWINCH: rtc.msg_type = STATE_ENABLE; break; default: /* should be impossible to reach */ abort(); } rtc.msg_len = strlen(state_messages[rtc.msg_type]); update_pid_file(&rtc); pthread_rwlock_unlock(&(rtc.lock)); #ifdef USE_SYSTEMD sd_journal_send("MESSAGE=signal received", "MESSAGE_ID=%s", SD_ID128_CONST_STR(MESSAGE_STATE_CHANGE), "NEW_STATE=%s", state_messages[rtc.msg_type], "PRIORITY=6", NULL); #else syslog(LOG_INFO, "signal received, state is %s", state_messages[rtc.msg_type]); #endif closelog(); }
void syslog_server( void ) { struct passwd *pass_struct; char *euid_pref, *dbhost_pref, *force_chroot; InitSQLconnection(); my_LoadChecker(); initSLogSocket(); dbhost_pref = GetConfigVar( "mysql-host" ); euid_pref = GetConfigVar( "effective-userid" ); force_chroot = GetConfigVar( "force-localhost-chroot" ); pass_struct = getpwnam( euid_pref ); if (strcmp(dbhost_pref,"localhost") || !strcmp(force_chroot, "yes")) { // We cannot chroot if connect to the DB via // a unix socket vs tcp chroot( CHROOT_PATH ); } if (pass_struct) { seteuid( pass_struct->pw_uid ); setegid( pass_struct->pw_gid ); } my_syslog( MLOG_SYSLOG, "docsis_server SYSLOG Version %s activated", VERSION); while(1) { // Update PID file update_pid_file(); // ping the MySQL server my_SQL_Ping(); getSLogPacket(); } }
void dhcp_server( void ) { char *iface_pref, *euid_pref, *dbhost_pref, *force_chroot; char *dhcp_high_load_c; int dhcp_high_load; dhcp_message message; u_int32_t server_ip; struct passwd *pass_struct; int retval = 0, cc = 0, sentreply; iface_pref = my_GetDHCPint(); server_ip = getInterfaceIP( iface_pref ); init_DHCP_Socket( server_ip ); // euid_pref = GetConfigVar( "effective-userid" ); // pass_struct = getpwnam( euid_pref ); // if (pass_struct) { // seteuid( pass_struct->pw_uid ); // setegid( pass_struct->pw_gid ); // } dbhost_pref = GetConfigVar( "mysql-host" ); force_chroot = GetConfigVar( "force-localhost-chroot" ); // if (strcmp(dbhost_pref,"localhost") || !strcmp(force_chroot, "yes")) { // // We cannot chroot if connect to the DB via // // a unix socket vs tcp // chroot( CHROOT_PATH ); // } dhcp_high_load_c = GetConfigVar( "dhcp-high-load" ); if (*dhcp_high_load_c == ' ') { dhcp_high_load_c = "16"; } dhcp_high_load = strtoul( dhcp_high_load_c, NULL, 10 ); if (dhcp_high_load <= 4) { dhcp_high_load = 4; } if (dhcp_high_load >= 128) { dhcp_high_load = 128; } my_Check_Load( dhcp_high_load ); InitSQLconnection(); my_syslog( MLOG_DHCP, "docsis_server DHCP version %s activated", VERSION); Clear_Remote_Commands(); while (dhcpd_exit_flag) { /* loop until universe collapses */ /* update the PID file */ update_pid_file(); /* Clear Message Struct */ memset( &message, 0, sizeof( dhcp_message ) ); retval = getPacket( &message ); if (retval == -2) Check_Remote_Commands(); if (retval < 0) { // ping the MySQL server my_SQL_Ping(); continue; } message.server_ip = server_ip; if (Check_Canary) { fprintf(stderr,"canary A died %llu %llu %llu " " %llu %llu %llu %llu %llu %llu\n",Canaries); continue; } DecodeOptions( &message ); if (message.in_opts.message_type == 0) { message.in_opts.message_type = DHCP_REQUEST; } if (Check_Canary) { fprintf(stderr,"canary B died %llu %llu %llu " " %llu %llu %llu %llu %llu %llu\n",Canaries); continue; } sentreply = 0; switch( message.in_opts.message_type ) { case DHCP_DISCOVER: sentreply = send_Offer( &message ); break; case DHCP_REQUEST: sentreply = send_ACK( &message ); break; case DHCP_RELEASE: /* checkRelease( &message ); */ break; case DHCP_INFORM: sentreply = send_ACK( &message ); break; case DHCP_DECLINE: /* ignore */ break; case DHCP_LEASE_QUERY: /* wierd ubR thingy 0x0d */ sentreply = leaseQuery( &message ); break; default: { my_syslog(LOG_WARNING, "unsupported DHCP message (%02x) %s -- ignoring", message.in_opts.message_type, message.s_macaddr ); } } if (Check_Canary) { fprintf(stderr,"canary C died %llu %llu %llu " " %llu %llu %llu %llu %llu %llu\n",Canaries); continue; } if (sentreply) my_Check_Load( dhcp_high_load ); Check_Remote_Commands(); } my_syslog(LOG_INFO, "exit"); Flush_ALL_SQL_Updates(); closelog(); exit(0); }
void tftp_server( void ) { int cc; struct timeval *tvp; time_t last, hour6, min1; socklen_t fromlen; struct sockaddr_in from; struct timeval tv; struct stat tftp_stat; struct passwd *pass_struct; char *euid_pref, *tftp_dir, *dbhost_pref, *force_chroot; char *tftp_high_load_c; int tftp_high_load; fd_set rfds; char buf[SEGSIZE + 4]; tftp_dir = my_GetTFTPdir(); if ( stat( tftp_dir, &tftp_stat ) != 0 ) { fprintf(stderr,"Could not read tftp dir: %s", tftp_dir ); exit(1); } chdir( tftp_dir ); Init_TFTP_Socket(); dbhost_pref = GetConfigVar( "mysql-host" ); euid_pref = GetConfigVar( "effective-userid" ); force_chroot = GetConfigVar( "force-localhost-chroot" ); pass_struct = getpwnam( euid_pref ); //if (strcmp(dbhost_pref,"localhost") || !strcmp(force_chroot, "yes")) { // We cannot chroot if connect to the DB via // a unix socket vs tcp // chroot( tftp_dir ); //} //if (pass_struct) { // seteuid( pass_struct->pw_uid ); // setegid( pass_struct->pw_gid ); //} tftp_high_load_c = GetConfigVar( "tftp-high-load" ); if (*tftp_high_load_c == ' ') { tftp_high_load_c = "16"; } tftp_high_load = strtoul( tftp_high_load_c, NULL, 10 ); if (tftp_high_load <= 4) { tftp_high_load = 4; } if (tftp_high_load >= 512) { tftp_high_load = 512; } my_Check_Load( tftp_high_load ); InitSQLconnection(); my_syslog( MLOG_TFTP, "docsis_server TFTP Version %s activated", VERSION ); Clear_Remote_Commands(); last = 0; hour6 = time(NULL); min1 = hour6; /* my_syslog( MLOG_TFTP, "tftp max num files %d", getdtablesize()); */ while (tftpd_exit_flag) { // Update the PID file update_pid_file(); FD_ZERO( &rfds ); FD_SET( tftp_socket, &rfds ); tv.tv_sec = 1; tv.tv_usec = 0; tvp = &tv; if (select(tftp_socket + 1, &rfds, NULL, NULL, &tv ) < 0) { /* Don't choke when we get ptraced */ if (errno == EINTR) continue; my_syslog( MLOG_ERROR, "tftp select: %s", strerror(errno) ); exit(1); } if (FD_ISSET( tftp_socket, &rfds ) ) { /* Process a packet */ fromlen = sizeof(from); cc = recvfrom(tftp_socket, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); if (cc < 0) { my_syslog( MLOG_ERROR, "tftp recvfrom: %s", strerror(errno) ); continue; } /* Update now */ now = time(NULL); /* Process this packet */ process(&from, (struct tftphdr *)buf, cc); my_Check_Load( tftp_high_load ); } else { now = time(NULL); } /* Run the timer list, no more than once a second */ if (clientlistcnt > 0) { if (last != now) { last = now; runtimer(); } } if ( (now - min1) >= 120) { min1 = now; free_file_cache(); // ping the MySQL server my_SQL_Ping(); } /* run the log stats 4 times a day */ if ( (now - hour6) >= 21600) { hour6 = now; logstats(); } Check_Remote_Commands(); } }