static void scrub_global_access_list( void ) { unsigned count; const char *func = "scrub_global_no_access_list"; if ( global_no_access == NULL ) count = 0; else count = pset_count( global_no_access ); if ( count ) { int found_one = 0; unsigned u; time_t nowtime = time(NULL); for (u=0; u < count; u++) { char *exp_time; time_t stored_time; exp_time = pset_pointer( global_no_access_time, u ) ; stored_time = atol(exp_time); if (stored_time == -1) /* never let them off */ continue; if (difftime(nowtime, (time_t)stored_time) >= 0.0) { __pset_pointer ptr; pset_pointer(global_no_access, u) = NULL; ptr = global_no_access_time->ptrs[ u ]; free(ptr); pset_pointer(global_no_access_time, u ) = NULL; found_one = 1; } } if (found_one) { pset_compact( global_no_access ); pset_compact( global_no_access_time ); msg(LOG_INFO, func, "At least 1 DENY_TIME has expired, global_no_access list updated"); } /* If there's still more on the list, start another callback. */ count = pset_count( global_no_access ); if ( count ) timer_id = xtimer_add( scrub_global_access_list, 60 ); else { timer_id = 0; msg(LOG_INFO, func, "global_no_access list is empty."); } } }
/* This actually gets called during initialization, so be careful what * gets put in here. */ void enable_periodic_check( unsigned interval ) { const char *func = "enable_periodic_check" ; if ( xtimer_add( periodic_check, interval ) == -1 ) { msg( LOG_ERR, func, "Failed to start consistency timer" ) ; return ; } }
static void consistency_check( enum check_type type ) { int fd ; fd_set socket_mask_copy ; unsigned u ; int errors ; unsigned total_running_servers = 0 ; unsigned total_retry_servers = 0 ; unsigned error_count = 0 ; bool_int service_count_check_failed = FALSE ; const char *func = "consistency_check" ; socket_mask_copy = ps.rws.socket_mask ; for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) { register struct service *sp = SP( pset_pointer( SERVICES( ps ), u ) ) ; char *sid = SVC_ID( sp ) ; unsigned running_servers ; unsigned retry_servers ; error_count += refcount_check( sp, &running_servers, &retry_servers ) ; if ( SVC_IS_AVAILABLE( sp ) || SVC_IS_DISABLED ( sp ) ) { /* * In this case, there may be some servers running */ if ( FD_ISSET( SVC_FD( sp ), &socket_mask_copy ) ) { if ( SVC_IS_DISABLED( sp ) ) { msg( LOG_ERR, func, "fd of disabled service %s still in socket mask", sid ) ; error_count++ ; } FD_CLR( SVC_FD( sp ), &socket_mask_copy ) ; } error_count += thread_check( sp, running_servers, retry_servers ) ; errors = service_count_check( sp, running_servers, retry_servers ) ; if ( ! errors && ! service_count_check_failed ) { total_retry_servers += retry_servers ; total_running_servers += running_servers ; } if ( errors ) { service_count_check_failed = TRUE ; error_count += errors ; } if ( SVC_IS_DISABLED( sp ) && SVC_RUNNING_SERVERS( sp ) == 0 ) { msg( LOG_ERR, func, "disabled service %s has 0 running servers\n", sid ) ; error_count++ ; continue ; } } else { msg( LOG_ERR, func, "service %s not started", SVC_ID( sp ) ) ; error_count++ ; } } if ( ! service_count_check_failed ) { if ( total_running_servers != pset_count( SERVERS( ps ) ) ) { msg( LOG_ERR, func, "total running servers (%d) != number of running servers (%d)", total_running_servers, pset_count( SERVERS( ps ) ) ) ; error_count++ ; } if ( total_retry_servers != pset_count( RETRIES( ps ) ) ) { msg( LOG_ERR, func, "total retry servers (%d) != number of retry servers (%d)", total_retry_servers, pset_count( RETRIES( ps ) ) ) ; error_count++ ; } } /* * Check if there are any descriptors set in socket_mask_copy */ for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ ) if ( FD_ISSET( fd, &socket_mask_copy ) && ((fd != signals_pending[0]) && fd != signals_pending[1])) { msg( LOG_ERR, func, "descriptor %d set in socket mask but there is no service for it", fd ) ; error_count++ ; } if ( error_count != 0 ) msg( LOG_WARNING, func, "Consistency check detected %d errors", error_count ) ; else if ( type == USER_REQUESTED || debug.on ) msg( LOG_INFO, func, "Consistency check passed" ) ; if( type == PERIODIC ) if ( xtimer_add( periodic_check, ps.ros.cc_interval ) == -1 ) msg( LOG_ERR, func, "Failed to start consistency timer" ) ; }
/* * This function runs in the parent context and updates the global_no_access * list. */ void process_sensor( const struct service *sp, const union xsockaddr *addr) { const char *func = "process_sensor"; if (SC_DENY_TIME(SVC_CONF(sp)) != 0) /* 0 simply logs it */ { if ( pset_count( global_no_access ) < MAX_GLOBAL_NO_ACCESS) { int item_matched = addrlist_match( global_no_access, SA(addr) ); if ( item_matched == 0) { /* no match...adding to the list */ char *dup_addr = new_string(xaddrname( addr ) ); if (dup_addr == NULL ) return ; if (addrlist_add(global_no_access, dup_addr) == FAILED) msg(LOG_ERR, func, "Failed adding %s to the global_no_access list", dup_addr); else { time_t nowtime; char time_buf[40], *tmp; nowtime = time(NULL); msg(LOG_CRIT, func, "Adding %s to the global_no_access list for %d minutes", dup_addr, SC_DENY_TIME(SVC_CONF(sp))); if (SC_DENY_TIME(SVC_CONF(sp)) == -1) strcpy(time_buf, "-1"); else strx_nprint(time_buf, 38, "%ld", (time_t)nowtime+(60*SC_DENY_TIME(SVC_CONF(sp)))); tmp = new_string(time_buf); if (tmp != NULL) { if (pset_add(global_no_access_time, tmp) == NULL) { msg(LOG_ERR, func, "Failed adding %s to the global_no_access_time list. " "global_no_access list is broken, xinetd needs " "restarting.", dup_addr); /* ideally, we should rollback the previous addr addition. */ } } if (pset_count(global_no_access) && (timer_id == 0) ) timer_id = xtimer_add( scrub_global_access_list, 60 ); } free(dup_addr); } else { /* Here again, eh?...update time stamp. */ char *exp_time; time_t stored_time; item_matched--; /* Is # plus 1, to even get here must be >= 1 */ exp_time = pset_pointer( global_no_access_time, item_matched ) ; if (exp_time == NULL) return ; if ( parse_base10(exp_time, (int *)&stored_time) ) { /* if never let them off, bypass */ if (stored_time != -1) { time_t nowtime, new_time; nowtime = time(NULL); new_time = (time_t)nowtime+(60*SC_DENY_TIME(SVC_CONF(sp))); if (difftime(new_time, (time_t)stored_time) > 0.0) { /* new_time is longer save it */ char time_buf[40], *new_exp_time; strx_nprint(time_buf, 38, "%ld", (long)new_time); new_exp_time = new_string(time_buf); if ( new_exp_time ) { free(exp_time); global_no_access_time->ptrs[ (unsigned)item_matched ] = new_exp_time; } } } } } } else msg(LOG_ERR, func, "Maximum global_no_access count reached."); } }