예제 #1
0
파일: ratelimit.c 프로젝트: gbour/kamailio
static void rpc_set_queue(rpc_t *rpc, void *c) {
	unsigned int queue_no = MAX_QUEUES, pipe_no = MAX_PIPES;
	str method, method_buf;


	if (rpc->scan(c, "dSd", &queue_no, &method, &pipe_no) < 3) return;

	if (pipe_no >= MAX_PIPES || (int)pipe_no < 0) {
		LM_ERR("Invalid pipe number: %d\n", pipe_no);
		rpc->fault(c, 400, "Invalid pipe number");
		return;
	}

	if (str_cpy(&method_buf, &method)) {
		LM_ERR("out of memory\n");
		rpc->fault(c, 400, "OOM");
		return;
	}

	LOCK_GET(rl_lock);
	if (queue_no >= *nqueues) {
		LM_ERR("MAX_QUEUES reached for queue: %d\n", queue_no);
		rpc->fault(c, 400, "MAX_QUEUES reached");
		LOCK_RELEASE(rl_lock);
		return;
	}

	*queues[queue_no].pipe = pipe_no;
	if (!queues[queue_no].method->s)
		shm_free(queues[queue_no].method->s);
	queues[queue_no].method->s = method_buf.s;
	queues[queue_no].method->len = method_buf.len;
	LOCK_RELEASE(rl_lock);
}
예제 #2
0
struct mi_root* mi_get_pid(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;
	node = add_mi_node_child(rpl, 0, "PID", 3, 0, 0);
	if(node == NULL)
		goto error;
	LOCK_GET(rl_lock);
	attr= addf_mi_attr(node, 0, "ki", 2, "%0.3f", *pid_ki);
	if(attr == NULL)
		goto error;
	attr= addf_mi_attr(node, 0, "kp", 2, "%0.3f", *pid_kp);
	if(attr == NULL)
		goto error;
	attr= addf_mi_attr(node, 0, "kd", 2, "%0.3f", *pid_kd);
	LOCK_RELEASE(rl_lock);
	if(attr == NULL)
		goto error;

	return rpl_tree;

error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree);
	return 0;
}
예제 #3
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
struct mi_root* mi_get_pipes(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;
	str algo;
	char* p;
	int i, len;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (*pipes[i].algo != PIPE_ALGO_NOP) {
			node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0);
			if(node == NULL)
				goto error;

			p = int2str((unsigned long)(i), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "id" , 2, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].algo), &len);
			if (str_map_int(algo_names, *pipes[i].algo, &algo))
				goto error;
			attr = add_mi_attr(node, 0, "algorithm", 9, algo.s, algo.len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].limit), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "limit", 5, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].counter), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len);
			if(attr == NULL)
				goto error;
		}
	}
	LOCK_RELEASE(rl_lock);
	return rpl_tree;
error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree); 
	return 0;
}
예제 #4
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
struct mi_root* mi_set_pipe(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	unsigned int pipe_no = MAX_PIPES, algo_id, limit = 0;
	//str algo;

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&pipe_no)<0)
		goto bad_syntax;
	
	node = node->next;
	if ( !node->value.s || !node->value.len)
		goto bad_syntax;
	if (str_map_str(algo_names, &(node->value), (int*)&algo_id)) {
		LM_ERR("unknown algorithm: '%.*s'\n", node->value.len, node->value.s);
		goto bad_syntax;
	}

	node = node->next;
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&limit)<0)
		goto bad_syntax;

	LM_DBG("set pipe: %d:%d:%d\n", pipe_no, algo_id, limit);

	if (pipe_no >= MAX_PIPES) {
		LM_ERR("wrong pipe_no: %d\n", pipe_no);
		goto bad_syntax;
	}

	LOCK_GET(rl_lock);
	*pipes[pipe_no].algo = algo_id;
	*pipes[pipe_no].limit = limit;

	if (check_feedback_setpoints(0)) {
		LM_ERR("feedback limits don't match\n");
		goto error;
	} else {
		*pid_setpoint = 0.01 * (double)cfg_setpoint;
	}

	set_check_network_load();
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
error:
	LOCK_RELEASE(rl_lock);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
예제 #5
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
struct mi_root* mi_set_queue(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	unsigned int queue_no = MAX_QUEUES, pipe_no = MAX_PIPES;
	str method;

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&queue_no)<0)
		goto bad_syntax;

	node = node->next;
	if ( !node->value.s || !node->value.len )
		goto bad_syntax;
	if (str_cpy(&method, &(node->value))) {
		LM_ERR("out of memory\n");
		goto early_error;
	}

	node = node->next;
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&pipe_no)<0)
		goto early_error;
	if (pipe_no >= MAX_PIPES) {
		LM_ERR("invalid pipe number: %d\n", pipe_no);
		goto early_error;
	}

	LOCK_GET(rl_lock);
	if (queue_no >= *nqueues) {
		LM_ERR("MAX_QUEUES reached for queue: %d\n", queue_no);
		goto error;
	}
	
	*queues[queue_no].pipe = pipe_no;
	if (!queues[queue_no].method->s)
		shm_free(queues[queue_no].method->s);
	queues[queue_no].method->s = method.s;
	queues[queue_no].method->len = method.len;
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
error:
	LOCK_RELEASE(rl_lock);
early_error:
	shm_free(method.s);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
예제 #6
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
/* mi function implementations */
struct mi_root* mi_stats(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;
	char* p;
	int i, len;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (*pipes[i].algo != PIPE_ALGO_NOP) {
			node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0);
			if(node == NULL)
				goto error;

			p = int2str((unsigned long)(i), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "id", 2, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].load), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "load", 4, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].last_counter), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len);
			if(attr == NULL)
				goto error;
		}
	}

	p = int2str((unsigned long)(*drop_rate), &len);
	node = add_mi_node_child(rpl, MI_DUP_VALUE, "DROP_RATE", 9, p, len);

	LOCK_RELEASE(rl_lock);
	return rpl_tree;
error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree); 
	return 0;
}
예제 #7
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
struct mi_root* mi_set_pid(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	char i[5], p[5], d[5];

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(i, node->value.s, node->value.len);
	i[node->value.len] = '\0';

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(p, node->value.s, node->value.len);
	p[node->value.len] = '\0';

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(d, node->value.s, node->value.len);
	d[node->value.len] = '\0';

	LOCK_GET(rl_lock);
	*pid_ki = strtod(i, NULL);
	*pid_kp = strtod(p, NULL);
	*pid_kd = strtod(d, NULL);
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
예제 #8
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
struct mi_root* mi_push_load(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	double value;
	char c[5];

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(c, node->value.s, node->value.len);
	c[node->value.len] = '\0';
	value = strtod(c, NULL);
	if (value < 0.0 || value > 1.0) {
		LM_ERR("value out of range: %0.3f in not in [0.0,1.0]\n", value);
		goto bad_syntax;
	}
	LOCK_GET(rl_lock);
	*load_value = value;
	LOCK_RELEASE(rl_lock);

	do_update_load();

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
예제 #9
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
struct mi_root* mi_set_dbg(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	unsigned int dbg_mode = 0;

	node = cmd_tree->node.kids; 
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&dbg_mode)<0)
		goto bad_syntax;

	LOCK_GET(rl_lock);
	if (dbg_mode) {
		if (!rl_dbg_str->s) {
			rl_dbg_str->len = (MAX_PIPES * 5 * sizeof(char));
			rl_dbg_str->s = (char *)shm_malloc(rl_dbg_str->len);
			if (!rl_dbg_str->s) {
				rl_dbg_str->len = 0;
				LM_ERR("oom: %d\n", rl_dbg_str->len);
			}
		}
	} else {
		if (rl_dbg_str->s) {
			shm_free(rl_dbg_str->s);
			rl_dbg_str->s = NULL;
			rl_dbg_str->len = 0;
		}
	}
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
예제 #10
0
파일: ratelimit.c 프로젝트: gbour/kamailio
static void rpc_set_pipe(rpc_t *rpc, void *c) {
	int pipe_no = MAX_PIPES, algo_id, limit = 0;
	str algo_str;

	if (rpc->scan(c, "dSd", &pipe_no, &algo_str, &limit) < 3) return;

	if (str_map_str(algo_names, &algo_str, &algo_id)) {
		LM_ERR("unknown algorithm: '%.*s'\n", algo_str.len, algo_str.s);
		rpc->fault(c, 400, "Unknown algorithm");
		return;
	}

	LM_DBG("set_pipe: %d:%d:%d\n", pipe_no, algo_id, limit);

	if (pipe_no >= MAX_PIPES || pipe_no < 0) {
		LM_ERR("wrong pipe_no: %d\n", pipe_no);
		rpc->fault(c, 400, "Unknown pipe");
		return;
	}

	LOCK_GET(rl_lock);
	*pipes[pipe_no].algo = algo_id;
	*pipes[pipe_no].limit = limit;

	if (check_feedback_setpoints(0)) {
		LM_ERR("feedback limits don't match\n");
		rpc->fault(c, 400, "Feedback limits don't match");
	} else {
		*pid_setpoint = 0.01 * (double)cfg_setpoint;
	}

	LOCK_RELEASE(rl_lock);
}
예제 #11
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
struct mi_root* mi_get_queues(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;
	char* p;
	int i, len;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_QUEUES; i++) {
		if (queues[i].pipe) {
			node = add_mi_node_child(rpl, 0, "QUEUE", 5, 0, 0);
			if(node == NULL)
				goto error;

			p = int2str((unsigned long)(i), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "id" , 2, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*queues[i].pipe), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "pipe" , 4, p, len);
			if(attr == NULL)
				goto error;

			attr = add_mi_attr(node, 0, "method", 6,
				(*queues[i].method).s, (*queues[i].method).len);
			if(attr == NULL)
				goto error;
		}
	}
	LOCK_RELEASE(rl_lock);

	return rpl_tree;
error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree); 
	return 0;
}
예제 #12
0
파일: ratelimit.c 프로젝트: gbour/kamailio
static void rpc_set_pid(rpc_t *rpc, void *c) {
	double ki, kp, kd;

	if (rpc->scan(c, "fff", &ki, &kp, &kd) < 3) return;

	LOCK_GET(rl_lock);
	*pid_ki = ki;
	*pid_kp = kp;
	*pid_kd = kd;
	LOCK_RELEASE(rl_lock);
}
예제 #13
0
파일: ratelimit.c 프로젝트: gbour/kamailio
/* rpc function implementations */
static void rpc_stats(rpc_t *rpc, void *c) {
	int i;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (rpc->printf(c, "PIPE[%d]: %d/%d (drop rate: %d)",
			i, *pipes[i].last_counter, *pipes[i].limit,
			*pipes[i].load) < 0) goto error;
	}
error:
	LOCK_RELEASE(rl_lock);
}
예제 #14
0
파일: adaptstm.c 프로젝트: HexHive/adaptSTM
static inline __always_inline void buf_release_all_locks(stm_tx_t *tx, stm_word_t version)
{
    /* release all write locks */
    lockset_t *mylocks = tx->lockset;
    stm_word_t i;
    if (version==0) {
	for (i=0; i<tx->nrlocks; i++) {
	    stm_word_t *lockaddr = mylocks[i].lock;
	    /* release the lock and save the version */
	    assert(*lockaddr==(stm_word_t)tx);
	    LOCK_RELEASE(lockaddr, mylocks[i].version);
	}
    } else {
	for (i=0; i<tx->nrlocks; i++) {
	    stm_word_t *lockaddr = mylocks[i].lock;
	    /* release the lock and save the version */
	    assert(*lockaddr==(stm_word_t)tx);
	    LOCK_RELEASE(lockaddr, version);
	}
    }
}
예제 #15
0
/* mi function implementations */
struct mi_root* mi_stats(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr *attr;
	int len;
	char * p;

	node = cmd_tree->node.kids;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;
	rpl->flags |= MI_IS_ARRAY;

	if (rl_stats(rpl_tree, &node->value)) {
		LM_ERR("cannot mi print values\n");
		goto free;
	}

	if (!(node = add_mi_node_child(rpl, 0, "PIPE", 4, NULL, 0)))
		goto free;

	LOCK_GET(rl_lock);
	p = int2str((unsigned long)(*drop_rate), &len);
	if (!(attr = add_mi_attr(node, MI_DUP_VALUE, "drop_rate", 9, p, len))) {
		LOCK_RELEASE(rl_lock);
		goto free;
	}

	LOCK_RELEASE(rl_lock);
	return rpl_tree;
free:
	free_mi_tree(rpl_tree);
	return 0;
}
예제 #16
0
파일: ratelimit.c 프로젝트: gbour/kamailio
static void rpc_get_queues(rpc_t *rpc, void *c) {
	int i;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_QUEUES; i++) {
		if (queues[i].pipe) {
			if (rpc->printf(c, "QUEUE[%d]: %d:%.*s",
				i, *queues[i].pipe,
				(*queues[i].method).len,
				(*queues[i].method).s) < 0) goto error;
		}
	}
error:
	LOCK_RELEASE(rl_lock);
}
예제 #17
0
파일: ratelimit.c 프로젝트: gbour/kamailio
static void rpc_push_load(rpc_t *rpc, void *c) {
	double value;

	if (rpc->scan(c, "f", &value) < 1) return;

	if (value < 0.0 || value > 1.0) {
		LM_ERR("value out of range: %0.3f in not in [0.0,1.0]\n", value);
		rpc->fault(c, 400, "Value out of range");
		return;
	}
	LOCK_GET(rl_lock);
	*load_value = value;
	LOCK_RELEASE(rl_lock);

	do_update_load();
}
예제 #18
0
파일: ratelimit.c 프로젝트: gbour/kamailio
static void rpc_get_pipes(rpc_t *rpc, void *c) {
	str algo;
	int i;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (*pipes[i].algo != PIPE_ALGO_NOP) {
			if (str_map_int(algo_names, *pipes[i].algo, &algo))
				goto error;
			if (rpc->printf(c, "PIPE[%d]: %d:%.*s %d/%d (drop rate: %d) [%d]",
				i, *pipes[i].algo, algo.len, algo.s,
				*pipes[i].last_counter, *pipes[i].limit,
				*pipes[i].load, *pipes[i].counter) < 0) goto error;
		}
	}
error:
	LOCK_RELEASE(rl_lock);
}
예제 #19
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
/* timer housekeeping, invoked each timer interval to reset counters */
static void rl_timer(unsigned int ticks, void *param)
{
	int i, len;
	char *c, *p;

	LOCK_GET(rl_lock);
	switch (*load_source) {
		case LOAD_SOURCE_CPU:
			update_cpu_load();
			break;
	}

	if (*check_network_load) {
		*network_load_value = get_total_bytes_waiting(PROTO_NONE);
	}

	if (rl_dbg_str->s) {
		c = p = rl_dbg_str->s;
		memset(c, ' ', rl_dbg_str->len);
		for (i=0; i<MAX_PIPES; i++) {
			c = int2str(*pipes[i].counter, &len);
			if (len < 4) {
				memcpy( p + (5-len), c, len );
			} else {
				memset(p, '*', 5);
				LM_WARN("Counter pipes[%d] to big: %d\n",
					i, *pipes[i].counter);
			}
			p = p + 5;
		}
		LM_WARN("%.*s\n", rl_dbg_str->len, rl_dbg_str->s);
	}

	for (i=0; i<MAX_PIPES; i++) {
		if( *pipes[i].algo == PIPE_ALGO_NETWORK ) {
			*pipes[i].load = ( *network_load_value > *pipes[i].limit ) ? 1 : -1;
		} else if (*pipes[i].limit && timer_interval) {
			*pipes[i].load = *pipes[i].counter / (*pipes[i].limit * timer_interval);
		}
		*pipes[i].last_counter = *pipes[i].counter;
		*pipes[i].counter = 0;
	}
	LOCK_RELEASE(rl_lock);
}
예제 #20
0
파일: ratelimit.c 프로젝트: gbour/kamailio
/* timer housekeeping, invoked each timer interval to reset counters */
static ticks_t rl_timer_handle(ticks_t ticks, struct timer_ln* tl, void* data)
{
	int i, len;
	char *c, *p;

	LOCK_GET(rl_lock);
	switch (*load_source) {
		case LOAD_SOURCE_CPU:
			update_cpu_load();
			break;
	}

	*network_load_value = get_total_bytes_waiting();

	if (rl_dbg_str->s) {
		c = p = rl_dbg_str->s;
		memset(c, ' ', rl_dbg_str->len);
		for (i=0; i<MAX_PIPES; i++) {
			c = int2str(*pipes[i].counter, &len);
			if (len < 4) {
				memcpy( p + (5-len), c, len );
			} else {
				memset(p, '*', 5);
				LM_WARN("Counter pipes[%d] to big: %d\n",
					i, *pipes[i].counter);
			}
			p = p + 5;
		}
		LM_WARN("%.*s\n", rl_dbg_str->len, rl_dbg_str->s);
	}

	for (i=0; i<MAX_PIPES; i++) {
		if( *pipes[i].algo == PIPE_ALGO_NETWORK ) {
			*pipes[i].load = ( *network_load_value > *pipes[i].limit ) ? 1 : -1;
		} else if (*pipes[i].limit && timer_interval) {
			*pipes[i].load = *pipes[i].counter / (*pipes[i].limit * timer_interval);
		}
		*pipes[i].last_counter = *pipes[i].counter;
		*pipes[i].counter = 0;
	}
	LOCK_RELEASE(rl_lock);
	return (ticks_t)(-1); /* periodical */
}
예제 #21
0
struct mi_root* mi_set_pid(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	char buf[5];
	int rl_ki, rl_kp, rl_kd;

	if (!(node = cmd_tree->node.kids))
		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);

	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;

	memcpy(buf, node->value.s, node->value.len);
	buf[node->value.len] = '\0';
	rl_ki = strtod(buf, NULL);

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(buf, node->value.s, node->value.len);
	buf[node->value.len] = '\0';
	rl_kp = strtod(buf, NULL);

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(buf, node->value.s, node->value.len);
	buf[node->value.len] = '\0';
	rl_kd = strtod(buf, NULL);

	LOCK_GET(rl_lock);
	*pid_ki = rl_ki;
	*pid_kp = rl_kp;
	*pid_kd = rl_kd;
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
예제 #22
0
/**
 * runs the current request through the queues
 * \param	forced_pipe	is >= 0 if a specific pipe should be used, < 0 otherwise
 * \return -1 if drop needed, 1 if allowed
 */
static int rl_check(struct sip_msg * msg, int forced_pipe)
{
	int que_id, pipe_id, ret;
	str method = msg->first_line.u.request.method;

	LOCK_GET(rl_lock);
	if (forced_pipe < 0) {
		if (find_queue(msg, &que_id)) {
			pipe_id = que_id = 0;
			ret = 1;
			goto out_release;
		}
		pipe_id = *queues[que_id].pipe;
	} else {
		que_id = 0; 
		pipe_id = forced_pipe;
	}

	ret = pipe_push(msg, pipe_id);
out_release:
	LOCK_RELEASE(rl_lock);

	/* no locks here because it's only read and pipes[pipe_id] is always alloc'ed */
	LOG(L_DBG,
			"meth=%.*s queue=%d pipe=%d algo=%d limit=%d pkg_load=%d counter=%d "
			"load=%2.1lf => %s\n",
			method.len,
			method.s, 
			que_id, 
			pipe_id,
			*pipes[pipe_id].algo,
			*pipes[pipe_id].limit,
			*pipes[pipe_id].load,
			*pipes[pipe_id].counter, 
			*load_value,
			(ret == 1) ? "ACCEPT" : "DROP");
	
	return ret;
}
예제 #23
0
파일: ratelimit.c 프로젝트: mtulio/mtulio
/**     
 * runs the current request through the queues
 * \param       forced_pipe     is >= 0 if a specific pipe should be used, < 0 otherwise
 * \return	-1 if drop needed, 1 if allowed
 */
static int rl_check(struct sip_msg * msg, int forced_pipe)
{
	int que_id, pipe_id, ret;
	str method = msg->first_line.u.request.method;

	if (forced_pipe >=0 && (forced_pipe>=MAX_PIPES || *pipes[forced_pipe].algo==PIPE_ALGO_NOP)) {
		LM_ERR("forced pipe %d out of range or not defined "
			" => defaulting to method type checking\n", forced_pipe);
		forced_pipe = -1;
	}

	LOCK_GET(rl_lock);
	if (forced_pipe < 0) { 
		if (find_queue(msg, &que_id)) {
			pipe_id = que_id = 0;
			ret = 1;
			goto out_release;
		}
		pipe_id = *queues[que_id].pipe;
	} else {
		que_id = 0;
		pipe_id = forced_pipe;
	}

	ret = pipe_push(msg, pipe_id);
out_release:
	LOCK_RELEASE(rl_lock);

	/* no locks here because it's only read and pipes[pipe_id] is always alloc'ed */
	LM_DBG("meth=%.*s queue=%d pipe=%d algo=%d limit=%d pkg_load=%d counter=%d "
		"load=%2.1lf network_load=%d => %s\n",
		method.len, method.s, que_id, pipe_id,
		*pipes[pipe_id].algo, *pipes[pipe_id].limit,
		*pipes[pipe_id].load, *pipes[pipe_id].counter,
		*load_value, *network_load_value, (ret == 1) ? "ACCEPT" : "DROP");

	return ret;
}
예제 #24
0
파일: ratelimit.c 프로젝트: gbour/kamailio
static void rpc_set_dbg(rpc_t *rpc, void *c) {
	int dbg_mode = 0;

	if (rpc->scan(c, "d", &dbg_mode) < 1) return;

	LOCK_GET(rl_lock);
	if (dbg_mode) {
		if (!rl_dbg_str->s) {
			rl_dbg_str->len = (MAX_PIPES * 5 * sizeof(char));
			rl_dbg_str->s = (char *)shm_malloc(rl_dbg_str->len);
			if (!rl_dbg_str->s) {
				rl_dbg_str->len = 0;
				LM_ERR("oom: %d\n", rl_dbg_str->len);
			}
		}
	} else {
		if (rl_dbg_str->s) {
			shm_free(rl_dbg_str->s);
			rl_dbg_str->s = NULL;
			rl_dbg_str->len = 0;
		}
	}
	LOCK_RELEASE(rl_lock);
}
예제 #25
0
void Text::setText(const char* text)
{
	int length = strlen(text);
	if(length > 255) length = 255;

	memset(pTextBuffer, 0x00, 256);
	memcpy(pTextBuffer, text, length);

	const char* p;

	int width=0,height=0;

    /* calculate font scaling */
	LOCK_ACQUIRE(gFtLock);
    //float scale = stbtt_ScaleForPixelHeight(gFontInfo, pPixelSize);
    float scale = stbtt_ScaleForMappingEmToPixels(gFontInfo, pPixelSize);

    int ascent, descent, lineGap;
    stbtt_GetFontVMetrics(gFontInfo, &ascent, &descent, &lineGap);

    ascent *= scale;
    descent *= scale;

    height = ascent;
    // calculate bitmap size
    for (p = pTextBuffer; *p; p++)
    {
        /* how wide is this character */
        int ax;
        stbtt_GetCodepointHMetrics(gFontInfo, p[0], &ax, 0);
        width += ax * scale;

        /* add kerning */
        int kern;
        kern = stbtt_GetCodepointKernAdvance(gFontInfo, p[0], p[1]);
        width += kern * scale;
    }

    //check if old bitmap exists, and delete it
	uint8_t* oldBitmap = pBitmap;
	pBitmap = (uint8_t*)malloc(width*height);
	if(oldBitmap)
	{
		free(oldBitmap);
	}


	memset(pBitmap,0,width*height);

	pBitmapWidth = width;
	pBitmapHeight = height;

	setSizeN(
			2.f*((float)pBitmapWidth)/GetCore()->screen_width,
			2.f*((float)pBitmapHeight)/GetCore()->screen_width
	);

	int x=0,y=0;

	// render text to buffer
	for (p = pTextBuffer; *p; p++)
    {
        /* get bounding box for character (may be offset to account for chars that dip above or below the line */
        int c_x1, c_y1, c_x2, c_y2;
        stbtt_GetCodepointBitmapBox(gFontInfo, p[0], scale, scale, &c_x1, &c_y1, &c_x2, &c_y2);

        /* compute y (different characters have different heights */
        y = ascent + c_y1;

        /* render character (stride and offset is important here) */
        int byteOffset = x + (y  * width);
        stbtt_MakeCodepointBitmap(gFontInfo, pBitmap + byteOffset, c_x2 - c_x1, c_y2 - c_y1, width, scale, scale, p[0]);

        /* how wide is this character */
        int ax;
        stbtt_GetCodepointHMetrics(gFontInfo, p[0], &ax, 0);
        x += ax * scale;

        /* add kerning */
        int kern;
        kern = stbtt_GetCodepointKernAdvance(gFontInfo, p[0], p[1]);
        x += kern * scale;
    }
	LOCK_RELEASE(gFtLock);

	updateBitmap = true;
}