Esempio n. 1
0
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);
	}
}
Esempio n. 2
0
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);
		}
	}
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
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();
	}
}
Esempio n. 5
0
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);
}
Esempio n. 6
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();
	}
}