Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
    }
}
Ejemplo n.º 4
0
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;
        }
      }
    }
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}