Beispiel #1
0
int uwsgi_cr_map_use_cache(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) {
	uint64_t hits = 0;
	uwsgi_rlock(ucr->cache->lock);
	char *value = uwsgi_cache_get4(ucr->cache, peer->key, peer->key_len, &peer->instance_address_len, &hits);
	if (!value) goto end;
	peer->tmp_socket_name = uwsgi_concat2n(value, peer->instance_address_len, "", 0);
	size_t nodes = uwsgi_str_occurence(peer->tmp_socket_name, peer->instance_address_len, '|');
	if (nodes > 0) {
		size_t choosen_node = hits % (nodes+1);
		size_t choosen_node_len = 0;
		peer->instance_address = uwsgi_str_split_nget(peer->tmp_socket_name, peer->instance_address_len, '|', choosen_node, &choosen_node_len);
		if (!peer->instance_address) goto end;
		peer->instance_address_len = choosen_node_len;
	}
	else {
		peer->instance_address = peer->tmp_socket_name;
	}
	char *cs_mod = uwsgi_str_contains(peer->instance_address, peer->instance_address_len, ',');
	if (cs_mod) {
		peer->modifier1 = uwsgi_str_num(cs_mod + 1, (peer->instance_address_len - (cs_mod - peer->instance_address)) - 1);
		peer->instance_address_len = (cs_mod - peer->instance_address);
	}
end:
	uwsgi_rwunlock(ucr->cache->lock);
	return 0;
}
Beispiel #2
0
static int uwsgi_api_cache_get(lua_State *L) {

        char *value ;
        uint64_t valsize;
	const char *key ;

        lca(L, 1);

	if (!uwsgi.caches) goto error;

	if (lua_isstring(L, 1)) {
		// get the key
		key = lua_tolstring(L, 1, NULL);
		uwsgi_rlock(uwsgi.caches->lock);
        	value = uwsgi_cache_get((char *)key, strlen(key), &valsize);
        	if (value) {
                	lua_pushlstring(L, value, valsize);
			uwsgi_rwunlock(uwsgi.caches->lock);
			return 1;
        	}
		uwsgi_rwunlock(uwsgi.caches->lock);

	}

error:

	lua_pushnil(L);

        return 1;

}
Beispiel #3
0
static void stats_pusher_dogstatsd(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {

  if (!uspi->configured) {
    struct dogstatsd_node *sn = uwsgi_calloc(sizeof(struct dogstatsd_node));
    char *comma = strchr(uspi->arg, ',');
    if (comma) {
      sn->prefix = comma+1;
      sn->prefix_len = strlen(sn->prefix);
      *comma = 0;
    }
    else {
      sn->prefix = "uwsgi";
      sn->prefix_len = 5;
    }

    char *colon = strchr(uspi->arg, ':');
    if (!colon) {
      uwsgi_log("invalid dd address %s\n", uspi->arg);
      if (comma) *comma = ',';
      free(sn);
      return;
    }
    sn->addr_len = socket_to_in_addr(uspi->arg, colon, 0, &sn->addr.sa_in);

    sn->fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sn->fd < 0) {
      uwsgi_error("stats_pusher_dogstatsd()/socket()");
      if (comma) *comma = ',';
                        free(sn);
                        return;
    }
    uwsgi_socket_nb(sn->fd);
    if (comma) *comma = ',';
    uspi->data = sn;
    uspi->configured = 1;
  }

  // we use the same buffer for all of the packets
  struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
  struct uwsgi_metric *um = uwsgi.metrics;
  while(um) {
    uwsgi_rlock(uwsgi.metrics_lock);
    // ignore return value
    if (um->type == UWSGI_METRIC_GAUGE) {
      dogstatsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|g");
    }
    else {
      dogstatsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|c");
    }
    uwsgi_rwunlock(uwsgi.metrics_lock);
    if (um->reset_after_push){
      uwsgi_wlock(uwsgi.metrics_lock);
      *um->value = um->initial_value;
      uwsgi_rwunlock(uwsgi.metrics_lock);
    }
    um = um->next;
  }
  uwsgi_buffer_destroy(ub);
}
Beispiel #4
0
static int uwsgi_websocket_send_from_sharedarea_do(struct wsgi_request *wsgi_req, int id, uint64_t pos, uint64_t len, uint8_t opcode) {
	struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
	if (!sa) return -1;
	if (!len) {
		len = sa->honour_used ? sa->used-pos : ((sa->max_pos+1)-pos);
	}
	uwsgi_rlock(sa->lock);
	sa->hits++;
        struct uwsgi_buffer *ub = uwsgi_websocket_message(wsgi_req, sa->area, len, opcode);
	uwsgi_rwunlock(sa->lock);
        if (!ub) return -1;

        return uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
}
Beispiel #5
0
static void stats_pusher_socket(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {

	if (!uspi->configured) {
		struct socket_node *sn = uwsgi_calloc(sizeof(struct socket_node));
		char *comma = strchr(uspi->arg, ',');

		if (comma) {
			sn->prefix = comma+1;
			sn->prefix_len = strlen(sn->prefix);
			*comma = 0;
		}
		else {
			sn->prefix = "uwsgi";
			sn->prefix_len = 5;
		}

		sn->fd = uwsgi_socket_from_addr(&sn->addr, &sn->addr_len, uspi->arg, SOCK_DGRAM);
		if (sn->fd < -1) {
			if (comma) *comma = ',';
			free(sn);
			return;
		}

        uwsgi_socket_nb(sn->fd);

		if (comma) *comma = ',';
		uspi->data = sn;
		uspi->configured = 1;
	}

	// we use the same buffer for all of the packets
	struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
	struct uwsgi_metric *um = uwsgi.metrics;
	while(um) {
		uwsgi_rlock(uwsgi.metrics_lock);
		socket_send_metric(ub, uspi, um);
		uwsgi_rwunlock(uwsgi.metrics_lock);
		if (um->reset_after_push){
			uwsgi_wlock(uwsgi.metrics_lock);
			*um->value = um->initial_value;
			uwsgi_rwunlock(uwsgi.metrics_lock);
		}
		um = um->next;
	}
	uwsgi_buffer_destroy(ub);
}
Beispiel #6
0
SSL_SESSION *uwsgi_ssl_session_get_cb(SSL *ssl, unsigned char *key, int keylen, int *copy) {

        uint64_t valsize = 0;

        *copy = 0;
        uwsgi_rlock(uwsgi.ssl_sessions_cache->lock);
        char *value = uwsgi_cache_get2(uwsgi.ssl_sessions_cache, (char *)key, keylen, &valsize);
        if (!value) {
                uwsgi_rwunlock(uwsgi.ssl_sessions_cache->lock);
                if (uwsgi.ssl_verbose) {
                        uwsgi_log("[uwsgi-ssl] cache miss\n");
                }
                return NULL;
        }
        SSL_SESSION *sess = d2i_SSL_SESSION(NULL, (const unsigned char **)&value, valsize);
        uwsgi_rwunlock(uwsgi.ssl_sessions_cache->lock);
        return sess;
}
Beispiel #7
0
struct uwsgi_stats *uwsgi_master_generate_stats() {

	int i;

	struct uwsgi_stats *us = uwsgi_stats_new(8192);

	if (uwsgi_stats_keyval_comma(us, "version", UWSGI_VERSION))
		goto end;

#ifdef __linux__
	if (uwsgi_stats_keylong_comma(us, "listen_queue", (unsigned long long) uwsgi.shared->options[UWSGI_OPTION_BACKLOG_STATUS]))
		goto end;
	if (uwsgi_stats_keylong_comma(us, "listen_queue_errors", (unsigned long long) uwsgi.shared->options[UWSGI_OPTION_BACKLOG_ERRORS]))
		goto end;
#endif

	int signal_queue = 0;
	if (ioctl(uwsgi.shared->worker_signal_pipe[1], FIONREAD, &signal_queue)) {
		uwsgi_error("uwsgi_master_generate_stats() -> ioctl()\n");
	}

	if (uwsgi_stats_keylong_comma(us, "signal_queue", (unsigned long long) signal_queue))
		goto end;

	if (uwsgi_stats_keylong_comma(us, "load", (unsigned long long) uwsgi.shared->load))
		goto end;
	if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) getpid()))
		goto end;
	if (uwsgi_stats_keylong_comma(us, "uid", (unsigned long long) getuid()))
		goto end;
	if (uwsgi_stats_keylong_comma(us, "gid", (unsigned long long) getgid()))
		goto end;

	char *cwd = uwsgi_get_cwd();
	if (uwsgi_stats_keyval_comma(us, "cwd", cwd)) {
		free(cwd);
		goto end;
	}
	free(cwd);

	if (uwsgi.daemons) {
		if (uwsgi_stats_key(us, "daemons"))
			goto end;
		if (uwsgi_stats_list_open(us))
			goto end;

		struct uwsgi_daemon *ud = uwsgi.daemons;
		while (ud) {
			if (uwsgi_stats_object_open(us))
				goto end;

			// allocate 2x the size of original command
			// in case we need to escape all chars
			char *cmd = uwsgi_malloc(strlen(ud->command)*2);
			escape_json(ud->command, strlen(ud->command), cmd);
			if (uwsgi_stats_keyval_comma(us, "cmd", cmd)) {
				free(cmd);
				goto end;
			}
			free(cmd);

			if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) (ud->pid < 0) ? 0 : ud->pid))
				goto end;
			if (uwsgi_stats_keylong(us, "respawns", (unsigned long long) ud->respawns ? 0 : ud->respawns))
				goto end;
			if (uwsgi_stats_object_close(us))
				goto end;
			if (ud->next) {
				if (uwsgi_stats_comma(us))
					goto end;
			}
			ud = ud->next;
		}
		if (uwsgi_stats_list_close(us))
			goto end;
		if (uwsgi_stats_comma(us))
			goto end;
	}

	if (uwsgi_stats_key(us, "locks"))
		goto end;
	if (uwsgi_stats_list_open(us))
		goto end;

	struct uwsgi_lock_item *uli = uwsgi.registered_locks;
	while (uli) {
		if (uwsgi_stats_object_open(us))
			goto end;
		if (uwsgi_stats_keylong(us, uli->id, (unsigned long long) uli->pid))
			goto end;
		if (uwsgi_stats_object_close(us))
			goto end;
		if (uli->next) {
			if (uwsgi_stats_comma(us))
				goto end;
		}
		uli = uli->next;
	}

	if (uwsgi_stats_list_close(us))
		goto end;
	if (uwsgi_stats_comma(us))
		goto end;

	if (uwsgi.caches) {

		
		if (uwsgi_stats_key(us, "caches"))
                goto end;

		if (uwsgi_stats_list_open(us)) goto end;

		struct uwsgi_cache *uc = uwsgi.caches;
		while(uc) {
			if (uwsgi_stats_object_open(us))
                        	goto end;

			if (uwsgi_stats_keyval_comma(us, "name", uc->name ? uc->name : "default"))
                        	goto end;

			if (uwsgi_stats_keyval_comma(us, "hash", uc->hash->name))
                        	goto end;

			if (uwsgi_stats_keylong_comma(us, "hashsize", (unsigned long long) uc->hashsize))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "keysize", (unsigned long long) uc->keysize))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "max_items", (unsigned long long) uc->max_items))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "blocks", (unsigned long long) uc->blocks))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "blocksize", (unsigned long long) uc->blocksize))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "items", (unsigned long long) uc->n_items))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "hits", (unsigned long long) uc->hits))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "miss", (unsigned long long) uc->miss))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "full", (unsigned long long) uc->full))
				goto end;

			if (uwsgi_stats_keylong(us, "last_modified_at", (unsigned long long) uc->last_modified_at))
				goto end;

			if (uwsgi_stats_object_close(us))
				goto end;

			if (uc->next) {
				if (uwsgi_stats_comma(us))
					goto end;
			}
			uc = uc->next;
		}

		if (uwsgi_stats_list_close(us))
		goto end;

		if (uwsgi_stats_comma(us))
		goto end;
	}

	if (uwsgi_stats_key(us, "sockets"))
		goto end;

	if (uwsgi_stats_list_open(us))
		goto end;

	struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
	while (uwsgi_sock) {
		if (uwsgi_stats_object_open(us))
			goto end;

		if (uwsgi_stats_keyval_comma(us, "name", uwsgi_sock->name))
			goto end;

		if (uwsgi_stats_keyval_comma(us, "proto", uwsgi_sock->proto_name ? uwsgi_sock->proto_name : "uwsgi"))
			goto end;

		if (uwsgi_stats_keylong_comma(us, "queue", (unsigned long long) uwsgi_sock->queue))
			goto end;

		if (uwsgi_stats_keylong_comma(us, "shared", (unsigned long long) uwsgi_sock->shared))
			goto end;

		if (uwsgi_stats_keylong(us, "can_offload", (unsigned long long) uwsgi_sock->can_offload))
			goto end;

		if (uwsgi_stats_object_close(us))
			goto end;

		uwsgi_sock = uwsgi_sock->next;
		if (uwsgi_sock) {
			if (uwsgi_stats_comma(us))
				goto end;
		}
	}

	if (uwsgi_stats_list_close(us))
		goto end;

	if (uwsgi_stats_comma(us))
		goto end;

	if (uwsgi_stats_key(us, "workers"))
		goto end;
	if (uwsgi_stats_list_open(us))
		goto end;

	for (i = 0; i < uwsgi.numproc; i++) {
		if (uwsgi_stats_object_open(us))
			goto end;

		if (uwsgi_stats_keylong_comma(us, "id", (unsigned long long) uwsgi.workers[i + 1].id))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) uwsgi.workers[i + 1].pid))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "requests", (unsigned long long) uwsgi.workers[i + 1].requests))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "delta_requests", (unsigned long long) uwsgi.workers[i + 1].delta_requests))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "exceptions", (unsigned long long) uwsgi_worker_exceptions(i + 1)))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "harakiri_count", (unsigned long long) uwsgi.workers[i + 1].harakiri_count))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "signals", (unsigned long long) uwsgi.workers[i + 1].signals))
			goto end;

		if (ioctl(uwsgi.workers[i + 1].signal_pipe[1], FIONREAD, &signal_queue)) {
			uwsgi_error("uwsgi_master_generate_stats() -> ioctl()\n");
		}

		if (uwsgi_stats_keylong_comma(us, "signal_queue", (unsigned long long) signal_queue))
			goto end;

		if (uwsgi.workers[i + 1].cheaped) {
			if (uwsgi_stats_keyval_comma(us, "status", "cheap"))
				goto end;
		}
		else if (uwsgi.workers[i + 1].suspended && !uwsgi_worker_is_busy(i+1)) {
			if (uwsgi_stats_keyval_comma(us, "status", "pause"))
				goto end;
		}
		else {
			if (uwsgi.workers[i + 1].sig) {
				if (uwsgi_stats_keyvalnum_comma(us, "status", "sig", (unsigned long long) uwsgi.workers[i + 1].signum))
					goto end;
			}
			else if (uwsgi_worker_is_busy(i+1)) {
				if (uwsgi_stats_keyval_comma(us, "status", "busy"))
					goto end;
			}
			else {
				if (uwsgi_stats_keyval_comma(us, "status", "idle"))
					goto end;
			}
		}

		if (uwsgi_stats_keylong_comma(us, "rss", (unsigned long long) uwsgi.workers[i + 1].rss_size))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "vsz", (unsigned long long) uwsgi.workers[i + 1].vsz_size))
			goto end;

		if (uwsgi_stats_keylong_comma(us, "running_time", (unsigned long long) uwsgi.workers[i + 1].running_time))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "last_spawn", (unsigned long long) uwsgi.workers[i + 1].last_spawn))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "respawn_count", (unsigned long long) uwsgi.workers[i + 1].respawn_count))
			goto end;

		if (uwsgi_stats_keylong_comma(us, "tx", (unsigned long long) uwsgi.workers[i + 1].tx))
			goto end;
		if (uwsgi_stats_keylong_comma(us, "avg_rt", (unsigned long long) uwsgi.workers[i + 1].avg_response_time))
			goto end;

		// applications list
		if (uwsgi_stats_key(us, "apps"))
			goto end;
		if (uwsgi_stats_list_open(us))
			goto end;

		int j;

		for (j = 0; j < uwsgi.workers[i + 1].apps_cnt; j++) {
			struct uwsgi_app *ua = &uwsgi.workers[i + 1].apps[j];

			if (uwsgi_stats_object_open(us))
				goto end;
			if (uwsgi_stats_keylong_comma(us, "id", (unsigned long long) j))
				goto end;
			if (uwsgi_stats_keylong_comma(us, "modifier1", (unsigned long long) ua->modifier1))
				goto end;

			if (uwsgi_stats_keyvaln_comma(us, "mountpoint", ua->mountpoint, ua->mountpoint_len))
				goto end;
			if (uwsgi_stats_keylong_comma(us, "startup_time", ua->startup_time))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "requests", ua->requests))
				goto end;
			if (uwsgi_stats_keylong_comma(us, "exceptions", ua->exceptions))
				goto end;

			if (ua->chdir) {
				if (uwsgi_stats_keyval(us, "chdir", ua->chdir))
					goto end;
			}
			else {
				if (uwsgi_stats_keyval(us, "chdir", ""))
					goto end;
			}

			if (uwsgi_stats_object_close(us))
				goto end;

			if (j < uwsgi.workers[i + 1].apps_cnt - 1) {
				if (uwsgi_stats_comma(us))
					goto end;
			}
		}


		if (uwsgi_stats_list_close(us))
			goto end;

		if (uwsgi_stats_comma(us))
			goto end;

		// cores list
		if (uwsgi_stats_key(us, "cores"))
			goto end;
		if (uwsgi_stats_list_open(us))
			goto end;

		for (j = 0; j < uwsgi.cores; j++) {
			struct uwsgi_core *uc = &uwsgi.workers[i + 1].cores[j];
			if (uwsgi_stats_object_open(us))
				goto end;
			if (uwsgi_stats_keylong_comma(us, "id", (unsigned long long) j))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "requests", (unsigned long long) uc->requests))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "static_requests", (unsigned long long) uc->static_requests))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "routed_requests", (unsigned long long) uc->routed_requests))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "offloaded_requests", (unsigned long long) uc->offloaded_requests))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "write_errors", (unsigned long long) uc->write_errors))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "in_request", (unsigned long long) uc->in_request))
				goto end;

			if (uwsgi_stats_key(us, "vars"))
				goto end;

			if (uwsgi_stats_list_open(us))
                        	goto end;

			if (uwsgi_stats_dump_vars(us, uc)) goto end;

			if (uwsgi_stats_list_close(us))
				goto end;


			if (uwsgi_stats_object_close(us))
				goto end;

			if (j < uwsgi.cores - 1) {
				if (uwsgi_stats_comma(us))
					goto end;
			}
		}

		if (uwsgi_stats_list_close(us))
			goto end;

		if (uwsgi_stats_object_close(us))
			goto end;

		if (i < uwsgi.numproc - 1) {
			if (uwsgi_stats_comma(us))
				goto end;
		}
	}

	if (uwsgi_stats_list_close(us))
		goto end;

	struct uwsgi_spooler *uspool = uwsgi.spoolers;
	if (uspool) {
		if (uwsgi_stats_comma(us))
			goto end;
		if (uwsgi_stats_key(us, "spoolers"))
			goto end;
		if (uwsgi_stats_list_open(us))
			goto end;
		while (uspool) {
			if (uwsgi_stats_object_open(us))
				goto end;

			if (uwsgi_stats_keyval_comma(us, "dir", uspool->dir))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) uspool->pid))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "tasks", (unsigned long long) uspool->tasks))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "respawns", (unsigned long long) uspool->respawned))
				goto end;

			if (uwsgi_stats_keylong(us, "running", (unsigned long long) uspool->running))
				goto end;

			if (uwsgi_stats_object_close(us))
				goto end;
			uspool = uspool->next;
			if (uspool) {
				if (uwsgi_stats_comma(us))
					goto end;
			}
		}
		if (uwsgi_stats_list_close(us))
			goto end;
	}

	struct uwsgi_cron *ucron = uwsgi.crons;
	if (ucron) {
		if (uwsgi_stats_comma(us))
			goto end;
		if (uwsgi_stats_key(us, "crons"))
			goto end;
		if (uwsgi_stats_list_open(us))
			goto end;
		while (ucron) {
			if (uwsgi_stats_object_open(us))
				goto end;

			if (uwsgi_stats_keyslong_comma(us, "minute", (long long) ucron->minute))
				goto end;

			if (uwsgi_stats_keyslong_comma(us, "hour", (long long) ucron->hour))
				goto end;

			if (uwsgi_stats_keyslong_comma(us, "day", (long long) ucron->day))
				goto end;

			if (uwsgi_stats_keyslong_comma(us, "month", (long long) ucron->month))
				goto end;

			if (uwsgi_stats_keyslong_comma(us, "week", (long long) ucron->week))
				goto end;

			char *cmd = uwsgi_malloc(strlen(ucron->command)*2);
			escape_json(ucron->command, strlen(ucron->command), cmd);
			if (uwsgi_stats_keyval_comma(us, "command", cmd)) {
				free(cmd);
				goto end;
			}
			free(cmd);

			if (uwsgi_stats_keylong_comma(us, "unique", (unsigned long long) ucron->unique))
				goto end;

#ifdef UWSGI_SSL
			if (uwsgi_stats_keyval_comma(us, "legion", ucron->legion ? ucron->legion : ""))
				goto end;
#endif

			if (uwsgi_stats_keyslong_comma(us, "pid", (long long) ucron->pid))
				goto end;

			if (uwsgi_stats_keylong(us, "started_at", (unsigned long long) ucron->started_at))
				goto end;

			if (uwsgi_stats_object_close(us))
				goto end;

			ucron = ucron->next;
			if (ucron) {
				if (uwsgi_stats_comma(us))
					goto end;
			}
		}
		if (uwsgi_stats_list_close(us))
			goto end;
	}

#ifdef UWSGI_SSL
	struct uwsgi_legion *legion = NULL;
	if (uwsgi.legions) {

		if (uwsgi_stats_comma(us))
			goto end;

		if (uwsgi_stats_key(us, "legions"))
			goto end;

		if (uwsgi_stats_list_open(us))
			goto end;

		legion = uwsgi.legions;
		while (legion) {
			if (uwsgi_stats_object_open(us))
				goto end;

			if (uwsgi_stats_keyval_comma(us, "legion", legion->legion))
				goto end;

			if (uwsgi_stats_keyval_comma(us, "addr", legion->addr))
				goto end;

			if (uwsgi_stats_keyval_comma(us, "uuid", legion->uuid))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "valor", (unsigned long long) legion->valor))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "checksum", (unsigned long long) legion->checksum))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "quorum", (unsigned long long) legion->quorum))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "i_am_the_lord", (unsigned long long) legion->i_am_the_lord))
				goto end;

			if (uwsgi_stats_keylong_comma(us, "lord_valor", (unsigned long long) legion->lord_valor))
				goto end;

			if (uwsgi_stats_keyvaln_comma(us, "lord_uuid", legion->lord_uuid, 36))
				goto end;

			// legion nodes start
			if (uwsgi_stats_key(us, "nodes"))
                                goto end;

                        if (uwsgi_stats_list_open(us))
                                goto end;

                        struct uwsgi_string_list *nodes = legion->nodes;
                        while (nodes) {

				if (uwsgi_stats_str(us, nodes->value))
                                	goto end;

                                nodes = nodes->next;
                                if (nodes) {
                                        if (uwsgi_stats_comma(us))
                                                goto end;
                                }
                        }

			if (uwsgi_stats_list_close(us))
				goto end;

                        if (uwsgi_stats_comma(us))
                        	goto end;


			// legion members start
			if (uwsgi_stats_key(us, "members"))
				goto end;

			if (uwsgi_stats_list_open(us))
				goto end;

			uwsgi_rlock(legion->lock);
			struct uwsgi_legion_node *node = legion->nodes_head;
			while (node) {
				if (uwsgi_stats_object_open(us))
					goto unlock_legion_mutex;

				if (uwsgi_stats_keyvaln_comma(us, "name", node->name, node->name_len))
					goto unlock_legion_mutex;

				if (uwsgi_stats_keyval_comma(us, "uuid", node->uuid))
					goto unlock_legion_mutex;

				if (uwsgi_stats_keylong_comma(us, "valor", (unsigned long long) node->valor))
					goto unlock_legion_mutex;

				if (uwsgi_stats_keylong_comma(us, "checksum", (unsigned long long) node->checksum))
					goto unlock_legion_mutex;

				if (uwsgi_stats_keylong(us, "last_seen", (unsigned long long) node->last_seen))
					goto unlock_legion_mutex;

				if (uwsgi_stats_object_close(us))
					goto unlock_legion_mutex;

				node = node->next;
				if (node) {
					if (uwsgi_stats_comma(us))
						goto unlock_legion_mutex;
				}
			}
			uwsgi_rwunlock(legion->lock);

			if (uwsgi_stats_list_close(us))
				goto end;
			// legion nodes end

			if (uwsgi_stats_object_close(us))
				goto end;

			legion = legion->next;
			if (legion) {
				if (uwsgi_stats_comma(us))
					goto end;
			}
		}

		if (uwsgi_stats_list_close(us))
			goto end;

	}
#endif

	if (uwsgi_stats_object_close(us))
		goto end;

	return us;
#ifdef UWSGI_SSL
unlock_legion_mutex:
	if (legion)
		uwsgi_rwunlock(legion->lock);
#endif
end:
	free(us->base);
	free(us);
	return NULL;
}
Beispiel #8
0
// this function does not use the magic api internally to avoid too much copy
static void manage_magic_context(struct wsgi_request *wsgi_req, struct uwsgi_cache_magic_context *ucmc) {

	struct uwsgi_buffer *ub = NULL;
	struct uwsgi_cache *uc = uwsgi.caches;

	if (ucmc->cache_len > 0) {
		uc = uwsgi_cache_by_namelen(ucmc->cache, ucmc->cache_len);
		if (!uc) return;
	}

	if (!uc) return;

	// cache get
	if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "get", 3)) {
		uint64_t vallen = 0;
		uint64_t expires = 0;
		uwsgi_rlock(uc->lock);
		char *value = uwsgi_cache_get3(uc, ucmc->key, ucmc->key_len, &vallen, &expires);
		if (!value) {
			uwsgi_rwunlock(uc->lock);
			return;
		}
		// we are still locked !!!
		ub = uwsgi_buffer_new(uwsgi.page_size);
		ub->pos = 4;
		if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
		if (uwsgi_buffer_append_keynum(ub, "size", 4, vallen)) goto error;
		if (expires) {
			if (uwsgi_buffer_append_keynum(ub, "expires", 7, expires)) goto error;
		}
		if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
		if (uwsgi_buffer_append(ub, value, vallen)) goto error;
		// unlock !!!
		uwsgi_rwunlock(uc->lock);
		uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
		uwsgi_buffer_destroy(ub);
		return;	
	}

	// cache exists
	if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "exists", 6)) {
                uwsgi_rlock(uc->lock);
                if (!uwsgi_cache_exists2(uc, ucmc->key, ucmc->key_len)) {
                        uwsgi_rwunlock(uc->lock);
                        return;
                }
                // we are still locked !!!
                ub = uwsgi_buffer_new(uwsgi.page_size);
                ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
                if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
                // unlock !!!
                uwsgi_rwunlock(uc->lock);
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
        }

	// cache del
        if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "del", 3)) {
                uwsgi_wlock(uc->lock);
                if (uwsgi_cache_del2(uc, ucmc->key, ucmc->key_len, 0, 0)) {
                        uwsgi_rwunlock(uc->lock);
                        return;
                }
                // we are still locked !!!
                ub = uwsgi_buffer_new(uwsgi.page_size);
                ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
                if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
                // unlock !!!
                uwsgi_rwunlock(uc->lock);
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
        }

	// cache clear
        if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "clear", 5)) {
		uint64_t i;
		uwsgi_wlock(uc->lock);
		for (i = 1; i < uwsgi.caches->max_items; i++) {
			if (uwsgi_cache_del2(uc, NULL, 0, i, 0)) {
                                uwsgi_rwunlock(uc->lock);
                                return;
                        }	
		}
                // we are still locked !!!
                ub = uwsgi_buffer_new(uwsgi.page_size);
                ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
                if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
                // unlock !!!
                uwsgi_rwunlock(uc->lock);
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
        }

	// cache set
	if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "set", 3) || !uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "update", 6)) {
		if (ucmc->size == 0 || ucmc->size > uc->max_item_size) return;
		wsgi_req->post_cl = ucmc->size;
		// read the value
		ssize_t rlen = 0;
		char *value = uwsgi_request_body_read(wsgi_req, ucmc->size, &rlen);
		if (rlen != (ssize_t) ucmc->size) return;
		// ok let's lock
		uwsgi_wlock(uc->lock);
		if (uwsgi_cache_set2(uc, ucmc->key, ucmc->key_len, value, ucmc->size, ucmc->expires, ucmc->cmd_len > 3 ? UWSGI_CACHE_FLAG_UPDATE : 0)) {
			uwsgi_rwunlock(uc->lock);
			return;
		}
		// we are still locked !!!
		ub = uwsgi_buffer_new(uwsgi.page_size);
		ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
		if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
		// unlock !!!
		uwsgi_rwunlock(uc->lock);
		uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
	}

	return;
error:
	uwsgi_rwunlock(uc->lock);
	uwsgi_buffer_destroy(ub);
}
Beispiel #9
0
int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_t document_root_len, char *path_info, uint16_t path_info_len, int is_a_file) {

	struct stat st;
	char real_filename[PATH_MAX + 1];
	size_t real_filename_len = 0;
	char *filename = NULL;
	size_t filename_len = 0;

	struct uwsgi_string_list *index = NULL;

	if (!is_a_file) {
		filename = uwsgi_concat3n(document_root, document_root_len, "/", 1, path_info, path_info_len);
		filename_len = document_root_len + 1 + path_info_len;
	}
	else {
		filename = uwsgi_concat2n(document_root, document_root_len, "", 0);
		filename_len = document_root_len;
	}

#ifdef UWSGI_DEBUG
	uwsgi_log("[uwsgi-fileserve] checking for %s\n", filename);
#endif

	if (uwsgi.static_cache_paths) {
		uwsgi_rlock(uwsgi.static_cache_paths->lock);
		uint64_t item_len;
		char *item = uwsgi_cache_get2(uwsgi.static_cache_paths, filename, filename_len, &item_len);
		if (item && item_len > 0 && item_len <= PATH_MAX) {
			memcpy(real_filename, item, item_len);
			real_filename_len = item_len;
			uwsgi_rwunlock(uwsgi.static_cache_paths->lock);
			goto found;
		}
		uwsgi_rwunlock(uwsgi.static_cache_paths->lock);
	}

	if (!realpath(filename, real_filename)) {
#ifdef UWSGI_DEBUG
		uwsgi_log("[uwsgi-fileserve] unable to get realpath() of the static file\n");
#endif
		free(filename);
		return -1;
	}
	real_filename_len = strlen(real_filename);

	if (uwsgi.static_cache_paths) {
		uwsgi_wlock(uwsgi.static_cache_paths->lock);
		uwsgi_cache_set2(uwsgi.static_cache_paths, filename, filename_len, real_filename, real_filename_len, uwsgi.use_static_cache_paths, UWSGI_CACHE_FLAG_UPDATE);
		uwsgi_rwunlock(uwsgi.static_cache_paths->lock);
	}

found:
	free(filename);

	if (uwsgi_starts_with(real_filename, real_filename_len, document_root, document_root_len)) {
		struct uwsgi_string_list *safe = uwsgi.static_safe;
		while(safe) {
			if (!uwsgi_starts_with(real_filename, real_filename_len, safe->value, safe->len)) {
				goto safe;
			}		
			safe = safe->next;
		}
		uwsgi_log("[uwsgi-fileserve] security error: %s is not under %.*s or a safe path\n", real_filename, document_root_len, document_root);
		return -1;
	}

safe:

	if (!uwsgi_static_stat(wsgi_req, real_filename, &real_filename_len, &st, &index)) {

		if (index) {
			// if we are here the PATH_INFO need to be changed
			if (uwsgi_req_append_path_info_with_index(wsgi_req, index->value, index->len)) {
                        	return -1;
                        }
		}

		// skip methods other than GET and HEAD
        	if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "GET", 3) && uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
			return -1;
        	}

		// check for skippable ext
		struct uwsgi_string_list *sse = uwsgi.static_skip_ext;
		while (sse) {
			if (real_filename_len >= sse->len) {
				if (!uwsgi_strncmp(real_filename + (real_filename_len - sse->len), sse->len, sse->value, sse->len)) {
					return -1;
				}
			}
			sse = sse->next;
		}

#ifdef UWSGI_ROUTING
		// before sending the file, we need to check if some rule applies
		if (!wsgi_req->is_routing && uwsgi_apply_routes_do(wsgi_req, NULL, 0) == UWSGI_ROUTE_BREAK) {
			return 0;
		}
		wsgi_req->routes_applied = 1;
#endif

		return uwsgi_real_file_serve(wsgi_req, real_filename, real_filename_len, &st);
	}

	return -1;

}
Beispiel #10
0
void manage_snmp(int fd, uint8_t * buffer, int size, struct sockaddr_in *client_addr) {

	uint16_t asnlen;
	uint16_t oidlen;

	uint8_t oid_part[2];

	int ptrdelta;

	uint8_t *ptr = buffer, *seq1, *seq2, *seq3;

	uint8_t community_len;

	uint64_t snmp_int = 0;
	uint64_t request_id = 0;
	uint64_t version = 0;


	// KISS for memory management
	if (size > SNMP_WATERMARK)
		return;
	ptr++;


	// check total sequence size
	if (*ptr > SNMP_WATERMARK || *ptr < 13)
		return;
	ptr++;

#ifdef UWSGI_DEBUG
	uwsgi_debug("SNMP packet size: %d\n", size);
#endif

	// check snmp version
	if (*ptr != SNMP_INTEGER)
		return;
	ptr++;

	ptrdelta = get_snmp_integer(ptr, &version);
	if (version > 2)
		return;
	ptr += ptrdelta;

#ifdef UWSGI_DEBUG
	uwsgi_debug("SNMP version: %d\n", version);
#endif

	// check for community string (this must be set from the api using uwsgi.snmp_community or with --snmp-community arg)
	if (*ptr != SNMP_STRING)
		return;
	ptr++;

	community_len = *ptr;

	if (community_len > 72 || community_len < 1)
		return;
	ptr++;

	// check for community string
	if (strlen(uwsgi.shared->snmp_community) != community_len)
		return;
	if (memcmp(ptr, uwsgi.shared->snmp_community, community_len))
		return;

#ifdef UWSGI_DEBUG
	uwsgi_debug("SNMP community: %.*s\n", community_len, ptr);
#endif

	ptr += community_len;

	// check for get request
	if (*ptr != SNMP_GET)
		return;

	*ptr = SNMP_RES;
	ptr++;
	seq1 = ptr;


	if (*ptr != ((size - community_len) - 9))
		return;
	ptr++;

	// get request_id
	if (*ptr != SNMP_INTEGER)
		return;
	ptr++;

	ptrdelta = get_snmp_integer(ptr, &request_id);

	if (ptrdelta <= 0)
		return;

#ifdef UWSGI_DEBUG
	uwsgi_debug("SNMP request id: %d %p\n", request_id, ptr);
#endif

	// check here
	if (ptr + ptrdelta >= buffer + size)
		return;
	ptr += ptrdelta;


	// get error
	if (*ptr != SNMP_INTEGER)
		return;

	ptr++;
	snmp_int = 0;
	ptrdelta = get_snmp_integer(ptr, &snmp_int);

	if (ptrdelta <= 0)
		return;
	if (ptr + ptrdelta >= buffer + size)
		return;
	if (snmp_int != 0)
		return;

	ptr += ptrdelta;

	// get index
	if (*ptr != SNMP_INTEGER)
		return;
	ptr++;
	snmp_int = 0;
	ptrdelta = get_snmp_integer(ptr, &snmp_int);
	if (ptrdelta <= 0)
		return;
	if (ptr + ptrdelta >= buffer + size)
		return;

	if (snmp_int != 0)
		return;
	ptr += ptrdelta;

#ifdef UWSGI_DEBUG
	uwsgi_debug("SNMP int [1]: %d\n", snmp_int);
#endif

	// check for sequence
	if (*ptr != SNMP_SEQUENCE)
		return;
	ptr++;


	if (*ptr > SNMP_WATERMARK)
		return;
	seq2 = ptr;
	ptr++;

	// now the interesting stuff: OID management
	if (*ptr != SNMP_SEQUENCE)
		return;
	ptr++;

	// check for normal OID uWSGI size: |1.3|.6|.1|.4|.1.|35156|.17|.1/2|.x| + OID_NULL
	asnlen = *ptr;
	if (asnlen < 15)
		return;
	seq3 = ptr;
	ptr++;

#ifdef UWSGI_DEBUG
	uwsgi_debug("SNMP ASN len: %d\n", asnlen);
#endif

	// is it an OID ?
	if (*ptr != SNMP_OID)
		return;
	ptr++;

	oidlen = *ptr;
	if (oidlen < 11)
		return;
	ptr++;

	// and now parse the OID !!!
	if (memcmp(ptr, SNMP_UWSGI_BASE, 9))
		return;

	ptr += 9;

	oid_part[0] = *ptr;

	// old style SNMP metrics
	if (oid_part[0] == 1 || oid_part[0] == 2) {
		ptr++;

		oid_part[1] = *ptr;
		if (oid_part[1] < 1 || oid_part[1] > 100)
			return;
		ptr++;

		// check for null
		if (memcmp((char *) ptr, "\x05\x00", 2))
			return;
		ptr += 2;
		size = build_snmp_response(oid_part[0], oid_part[1], buffer, size, seq1, seq2, seq3);
	}
	// metrics subsystem
	else {
		size_t metric_asn_len = oidlen - 9;
		char *metric_asn = (char *) ptr;
		struct uwsgi_metric *um = uwsgi_metric_find_by_asn(metric_asn, metric_asn_len);
		if (!um) return;
		uwsgi_rlock(uwsgi.metrics_lock);
		int64_t value = *um->value;
		uwsgi_rwunlock(uwsgi.metrics_lock);
		size = build_snmp_metric_response(value, um->type, buffer, size, seq1, seq2, seq3);
	}


	if (size > 0) {
		if (sendto(fd, buffer, size, 0, (struct sockaddr *) client_addr, sizeof(struct sockaddr_in)) < 0) {
			uwsgi_error("sendto()");
		}
	}
}