static int sb_get_idle_worker() { int i, j, res; worker_score *ws_record; process_score *ps_record; int idle = 0; #ifdef __APACHE24__ ap_generation_t ap_my_generation; ap_mpm_query(AP_MPMQ_GENERATION, &ap_my_generation); #endif ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &mruby_thread_limit); ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &mruby_server_limit); if (!ap_extended_status) return idle; for (i = 0; i < mruby_server_limit; ++i) { ps_record = ap_get_scoreboard_process(i); for (j = 0; j < mruby_thread_limit; ++j) { ws_record = ap_get_scoreboard_worker(i, j); res = ws_record->status; if (!ps_record->quiescing && ps_record->pid) { if (res == SERVER_READY && ps_record->generation == ap_my_generation) idle++; } } } return idle; }
static int update_echo_child_status(ap_sb_handle_t *sbh, int status, conn_rec *c, apr_bucket_brigade *last_echoed) { worker_score *ws = ap_get_scoreboard_worker(sbh); int old_status = ws->status; ws->status = status; if (!ap_extended_status) return old_status; ws->last_used = apr_time_now(); /* initial pass only, please - in the name of efficiency */ if (c) { apr_cpystrn(ws->client, ap_get_remote_host(c, c->base_server->lookup_defaults, REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); apr_cpystrn(ws->vhost, c->base_server->server_hostname, sizeof(ws->vhost)); /* Deliberate trailing space - filling in string on WRITE passes */ apr_cpystrn(ws->request, "ECHO ", sizeof(ws->request)); } /* each subsequent WRITE pass, let's update what we echoed */ if (last_echoed) { brigade_peek(last_echoed, ws->request + sizeof("ECHO ") - 1, sizeof(ws->request) - sizeof("ECHO ") + 1); } return old_status; }
static int pre_connection(conn_rec *c) { llzr_config *conf = ap_get_module_config (c->base_server->module_config, &llzr_module); sb_handle *sbh = c->sbh; redis = conf->redisconn; reply = conf->redisreply; /* loop index variables */ int i; int j; /* running count of number of connections from this address */ int ip_count = 0; /* scoreboard data structure */ worker_score *ws_record; ws_record = &ap_scoreboard_image->servers[sbh->child_num][sbh->thread_num]; apr_cpystrn(ws_record->client, c->remote_ip, sizeof(ws_record->client)); char *client_ip = ws_record->client; /* Count up the number of connections we are handling right now from this IP address */ for (i = 0; i < server_limit; ++i) { for (j = 0; j < thread_limit; ++j) { ws_record = ap_get_scoreboard_worker(i, j); switch (ws_record->status) { case SERVER_BUSY_READ: if (strcmp(client_ip, ws_record->client) == 0) ip_count++; break; default: break; } } } if (ip_count > conf->limit) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, "Rejected, too many connections in READ state from %s", c->remote_ip); return OK; } else { return DECLINED; } }
static apr_off_t sb_get_kbcount() { int i, j, res; unsigned long lres; apr_off_t bytes; apr_off_t bcount, kbcount; worker_score *ws_record; //process_score *ps_record; ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &mruby_thread_limit); ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &mruby_server_limit); bcount = 0; kbcount = 0; if (!ap_extended_status) return kbcount; for (i = 0; i < mruby_server_limit; ++i) { //ps_record = ap_get_scoreboard_process(i); for (j = 0; j < mruby_thread_limit; ++j) { ws_record = ap_get_scoreboard_worker(i, j); res = ws_record->status; lres = ws_record->access_count; bytes = ws_record->bytes_served; if (lres != 0 || (res != SERVER_READY && res != SERVER_DEAD)) { bcount += bytes; if (bcount >= KBYTE) { kbcount += (bcount >> 10); bcount = bcount & 0x3ff; } } }
static sc_clocks_t ap_mrb_get_sc_clocks() { #ifdef HAVE_TIMES int times_per_thread; sc_clocks_t cur, proc, tmp; unsigned long lres; int res, i, j; worker_score *ws_record; #endif #ifdef __APACHE24__ ap_generation_t ap_my_generation; ap_mpm_query(AP_MPMQ_GENERATION, &ap_my_generation); #endif ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &mruby_thread_limit); ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &mruby_server_limit); #ifdef HAVE_TIMES times_per_thread = getpid() != child_pid; #endif for (i = 0; i < mruby_server_limit; ++i) { #ifdef HAVE_TIMES //clock_t proc_tu = 0, proc_ts = 0, proc_tcu = 0, proc_tcs = 0; //clock_t tmp_tu, tmp_ts, tmp_tcu, tmp_tcs; proc.tu = 0; proc.ts = 0; proc.tcu = 0; proc.tcs = 0; #endif for (j = 0; j < mruby_thread_limit; ++j) { ws_record = ap_get_scoreboard_worker(i, j); res = ws_record->status; if (ap_extended_status) { lres = ws_record->access_count; if (lres != 0 || (res != SERVER_READY && res != SERVER_DEAD)) { #ifdef HAVE_TIMES tmp.tu = ws_record->times.tms_utime; tmp.ts = ws_record->times.tms_stime; tmp.tcu = ws_record->times.tms_cutime; tmp.tcs = ws_record->times.tms_cstime; if (times_per_thread) { proc.tu += tmp.tu; proc.ts += tmp.ts; proc.tcu += tmp.tcu; proc.tcs += tmp.tcs; } else { if (tmp.tu > proc.tu || tmp.ts > proc.ts || tmp.tcu > proc.tcu || tmp.tcs > proc.tcs) { proc.tu = tmp.tu; proc.ts = tmp.ts; proc.tcu = tmp.tcu; proc.tcs = tmp.tcs; } } #endif /* HAVE_TIMES */ } } } #ifdef HAVE_TIMES cur.tu += proc.tu; cur.ts += proc.ts; cur.tcu += proc.tcu; cur.tcs += proc.tcs; #endif } return cur; }
static PyObject *wsgi_server_metrics(void) { PyObject *scoreboard_dict = NULL; PyObject *process_list = NULL; PyObject *object = NULL; apr_time_t current_time; apr_interval_time_t running_time; global_score *gs_record; worker_score *ws_record; process_score *ps_record; int j, i; if (!wsgi_interns_initialized) wsgi_initialize_interned_strings(); /* Scoreboard needs to exist and server metrics enabled. */ if (!ap_exists_scoreboard_image()) { Py_INCREF(Py_None); return Py_None; } if (!wsgi_daemon_pool) { if (!wsgi_server_config->server_metrics) { Py_INCREF(Py_None); return Py_None; } } #if defined(MOD_WSGI_WITH_DAEMONS) else { if (!wsgi_daemon_process->group->server_metrics) { Py_INCREF(Py_None); return Py_None; } } #endif gs_record = ap_get_scoreboard_global(); if (!gs_record) { Py_INCREF(Py_None); return Py_None; } /* Return everything in a dictionary. Start with global. */ scoreboard_dict = PyDict_New(); object = wsgi_PyInt_FromLong(gs_record->server_limit); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(server_limit), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(gs_record->thread_limit); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(thread_limit), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(gs_record->running_generation); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(running_generation), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec(( double)gs_record->restart_time)); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(restart_time), object); Py_DECREF(object); current_time = apr_time_now(); object = PyFloat_FromDouble(apr_time_sec((double)current_time)); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(current_time), object); Py_DECREF(object); running_time = (apr_uint32_t)apr_time_sec((double) current_time - ap_scoreboard_image->global->restart_time); object = wsgi_PyInt_FromLongLong(running_time); PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(running_time), object); Py_DECREF(object); /* Now add in the processes/workers. */ process_list = PyList_New(0); for (i = 0; i < gs_record->server_limit; ++i) { PyObject *process_dict = NULL; PyObject *worker_list = NULL; ps_record = ap_get_scoreboard_process(i); process_dict = PyDict_New(); PyList_Append(process_list, process_dict); object = wsgi_PyInt_FromLong(i); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(process_num), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(ps_record->pid); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(pid), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(ps_record->generation); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(generation), object); Py_DECREF(object); object = PyBool_FromLong(ps_record->quiescing); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(quiescing), object); Py_DECREF(object); worker_list = PyList_New(0); PyDict_SetItem(process_dict, WSGI_INTERNED_STRING(workers), worker_list); for (j = 0; j < gs_record->thread_limit; ++j) { PyObject *worker_dict = NULL; #if AP_MODULE_MAGIC_AT_LEAST(20071023,0) ws_record = ap_get_scoreboard_worker_from_indexes(i, j); #else ws_record = ap_get_scoreboard_worker(i, j); #endif worker_dict = PyDict_New(); PyList_Append(worker_list, worker_dict); object = wsgi_PyInt_FromLong(ws_record->thread_num); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(thread_num), object); Py_DECREF(object); object = wsgi_PyInt_FromLong(ws_record->generation); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(generation), object); Py_DECREF(object); object = wsgi_status_flags[ws_record->status]; PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(status), object); object = wsgi_PyInt_FromLong(ws_record->access_count); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(access_count), object); Py_DECREF(object); object = wsgi_PyInt_FromUnsignedLongLong(ws_record->bytes_served); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(bytes_served), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec( (double)ws_record->start_time)); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(start_time), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec( (double)ws_record->stop_time)); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(stop_time), object); Py_DECREF(object); object = PyFloat_FromDouble(apr_time_sec( (double)ws_record->last_used)); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(last_used), object); Py_DECREF(object); object = wsgi_PyString_FromString(ws_record->client); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(client), object); Py_DECREF(object); object = wsgi_PyString_FromString(ws_record->request); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(request), object); Py_DECREF(object); object = wsgi_PyString_FromString(ws_record->vhost); PyDict_SetItem(worker_dict, WSGI_INTERNED_STRING(vhost), object); Py_DECREF(object); Py_DECREF(worker_dict); } Py_DECREF(worker_list); Py_DECREF(process_dict); } PyDict_SetItem(scoreboard_dict, WSGI_INTERNED_STRING(processes), process_list); Py_DECREF(process_list); return scoreboard_dict; }
static int ipblock_handler(request_rec *r, int lookup_uri) { #else static int ipblock_handler(request_rec *r) { #endif /* get configuration information */ ipblock_config *cfg = (ipblock_config *) ap_get_module_config(r->server->module_config, &ipblock_module); /* A limit value of 0 or less, by convention, means no limit. */ if (cfg->limit <= 0) return DECLINED; /* loop index variables */ int i; int j; /* running count of number of connections from this address */ int ip_count = 0; #ifdef APACHE2 /* scoreboard data structure */ worker_score *ws_record; #else /* scoreboard data structure */ short_score score_record; #endif /* We decline to handle subrequests: otherwise, in the next step we * could get into an infinite loop. */ if (!ap_is_initial_req(r)) { #ifdef APACHE2 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "SKIPPED: Not initial request"); #else ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, "SKIPPED: Not initial request"); #endif return DECLINED; } /* Count up the number of connections we are handling right now from this IP address */ #ifdef APACHE2 for (i = 0; i < server_limit; ++i) { for (j = 0; j < thread_limit; ++j) { ws_record = ap_get_scoreboard_worker(i, j); switch (ws_record->status) { case SERVER_BUSY_READ: case SERVER_BUSY_WRITE: case SERVER_BUSY_KEEPALIVE: case SERVER_BUSY_LOG: case SERVER_BUSY_DNS: case SERVER_CLOSING: case SERVER_GRACEFUL: if (strcmp(r->connection->remote_ip, ws_record->client) == 0) ip_count++; break; default: break; } } } #else for (i = 0; i < HARD_SERVER_LIMIT; ++i) { score_record = ap_scoreboard_image->servers[i]; switch (score_record.status) { case SERVER_BUSY_READ: case SERVER_BUSY_WRITE: case SERVER_BUSY_KEEPALIVE: case SERVER_BUSY_DNS: case SERVER_GRACEFUL: if ((strcmp(r->connection->remote_ip, score_record.client) == 0) #ifdef RECORD_FORWARD || (strcmp(ap_table_get(r->headers_in, "X-Forwarded-For"), score_record.fwdclient) == 0) #endif ) { ip_count++; } break; case SERVER_DEAD: case SERVER_READY: case SERVER_STARTING: case SERVER_BUSY_LOG: break; } } #endif /* APACHE2 */ #ifdef APACHE2 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, #else ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, #endif "vhost: %s uri: %s current: %d limit: %d", r->server->server_hostname, r->uri, ip_count, cfg->limit); if (ip_count > cfg->limit) { #ifdef APACHE2 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Rejected, too many connections from this host."); #else ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "Rejected, too many connections from this host."); #endif /* set an environment variable */ #ifdef APACHE2 apr_table_setn(r->subprocess_env, "BLOCKIP", "1"); #else ap_table_setn(r->subprocess_env, "BLOCKIP", "1"); #endif char *args[4]; args[0] = cfg->cmd; args[1] = r->connection->remote_ip; #ifdef APACHE2 args[2] = apr_psprintf(r->pool, "%d %d %s%s", (int) ip_count, (int) cfg->limit, r->server->server_hostname, r->uri); #else args[2] = ap_psprintf(r->pool, "%d %d %s%s", (int) ip_count, (int) cfg->limit, r->server->server_hostname, r->uri); #endif args[3] = NULL; execve(cfg->cmd, args, NULL); /* return 503 */ return HTTP_SERVICE_UNAVAILABLE; } return OK; }