/*
 * destroy function
 */
static void destroy(void)
{
	LM_NOTICE("destroy module ...\n");
	close(sockets.unix_sock);
	close(sockets.udp_sock);
}
Ejemplo n.º 2
0
/*! \brief
 * Init module function
 */
static int mod_init(void)
{
	if(register_mi_mod(exports.name, mi_cmds)!=0)
	{
		LM_ERR("failed to register MI commands\n");
		return -1;
	}

	/* Group matching feature */
	if (file == NULL) {
		LM_NOTICE("'file' parameter is not set, group matching disabled\n");
	} else {
		/* Create and init the lock */
		reload_lock = lock_alloc();
		if (reload_lock == NULL) {
			LM_ERR("cannot allocate reload_lock\n");
			goto err;
		}
		if (lock_init(reload_lock) == NULL) {
			LM_ERR("cannot init the reload_lock\n");
			lock_dealloc(reload_lock);
			goto err;
		}
		
		/* PCRE options */
		if (pcre_caseless != 0) {
			LM_DBG("PCRE CASELESS enabled\n");
			pcre_options = pcre_options | PCRE_CASELESS;
		}
		if (pcre_multiline != 0) {
			LM_DBG("PCRE MULTILINE enabled\n");
			pcre_options = pcre_options | PCRE_MULTILINE;
		}
		if (pcre_dotall != 0) {
			LM_DBG("PCRE DOTALL enabled\n");
			pcre_options = pcre_options | PCRE_DOTALL;
		}
		if (pcre_extended != 0) {
			LM_DBG("PCRE EXTENDED enabled\n");
			pcre_options = pcre_options | PCRE_EXTENDED;
		}
		LM_DBG("PCRE options: %i\n", pcre_options);
		
		/* Pointer to pcres */
		if ((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) {
			LM_ERR("no memory for pcres_addr\n");
			goto err;
		}
		
		/* Integer containing the number of pcres */
		if ((num_pcres = shm_malloc(sizeof(int))) == 0) {
			LM_ERR("no memory for num_pcres\n");
			goto err;
		}
		
		/* Load the pcres */
		LM_DBG("loading pcres...\n");
		if (load_pcres(START)) {
			LM_ERR("failed to load pcres\n");
			goto err;
		}
	}
	
	return 0;
	
err:
	free_shared_memory();
	return -1;
}
Ejemplo n.º 3
0
int is_other_contact_f(struct sip_msg* msg, char* _d, char *_s)
{
	pv_spec_p spec = (pv_spec_p)_s;
	struct usr_avp *avp = NULL;
	urecord_t *r = NULL;
	str ip, contact;
	str uri, aor;
	ucontact_t *c;
	contact_t* ct;
	int exp, found;
	udomain_t* ud = (udomain_t*)_d;
	
	if (parse_message(msg) < 0) {
		LM_ERR("unable to parse message\n");
		return -2;
	}
	if (!ud) {
		LM_ERR("no location specified\n");
		return -2;
	}
	/* msg doesn't have contacts */
	if (!msg->contact ||
			!(ct = (((contact_body_t*)msg->contact->parsed)->contacts)))
		return -1;


	while (ct) {
		/* if expires is 0 */
		calc_contact_expires(msg, ct->expires, &exp, NULL);
		if (exp)
			break;
		ct = ct->next;
	}

	if (!ct) {
		LM_DBG("contact has expire 0\n");
		return -1;
	}

	uri = get_to(msg)->uri;

	if (extract_aor(&uri, &aor,0,0) < 0) {
		LM_ERR("failed to extract AOR record\n");
		return -2;
	}

	ul.lock_udomain(ud, &aor);
	ul.get_urecord(ud, &aor, &r);
	if (!r) {
		/* dont't test anything */
		LM_DBG("no contact found for aor=<%.*s>\n", aor.len, aor.s);
		found = -1;
		goto end;
	} else {
		c = r->contacts;
	}	

	while (c) {
		if (!c->received.len || !c->received.s || c->received.len < 4 /* sip:*/) {
			c = c->next;
			continue;
		}

		contact.s = c->received.s + 4;
		/* check for "sips:" */
		if (*contact.s == ':') {
			contact.len = c->received.len - 5;
			contact.s++;
		} else {
			/* skip "sip:" */
			contact.len = c->received.len - 4;
		}

		avp = NULL;
		found = 0;

		/* the ip should always be a string */
		while ((avp = search_first_avp(spec->pvp.pvn.u.isname.type,
						spec->pvp.pvn.u.isname.name.n, (int_str *)&ip, avp))!=0) {
			if (!(avp->flags & AVP_VAL_STR)) {
				LM_NOTICE("avp value should be string\n");
				continue;
			}
			if ((contact.len == ip.len || (contact.len>ip.len && contact.s[ip.len]==':'))
					&& !memcmp(contact.s, ip.s, ip.len)) {
				found = 1;
				break;
			}
		}

		if (!found) {
			LM_DBG("no contact <%.*s> registered earlier\n",
					contact.len, contact.s);
			found = 1;
			goto end;
		}

		c = c->next;
	}
	found = -1;

end:
	ul.unlock_udomain(ud, &aor);
	return found;
}
Ejemplo n.º 4
0
/**
 * Main routine, start of the program execution.
 * \param argc the number of arguments
 * \param argv pointer to the arguments array
 * \return don't return on sucess, -1 on error
 * \see main_loop
 */
int main(int argc, char** argv)
{
	/* configure by default logging to syslog */
	int cfg_log_stderr = 0;
	FILE* cfg_stream;
	int c,r;
	char *tmp;
	int tmp_len;
	int port;
	int proto;
	char *options;
	int ret;
	unsigned int seed;
	int rfd;

	/*init*/
	ret=-1;
	my_argc=argc; my_argv=argv;

	/* process pkg mem size from command line */
	opterr=0;
	options="f:cCm:M:b:l:n:N:rRvdDETSVhw:t:u:g:P:G:W:o:";

	while((c=getopt(argc,argv,options))!=-1){
		switch(c){
			case 'M':
					pkg_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
					if (tmp &&(*tmp)){
						LM_ERR("bad pkgmem size number: -m %s\n", optarg);
						goto error00;
					};

					break;
		}
	}
	/*init pkg mallocs (before parsing cfg but after parsing cmd line !)*/
	if (init_pkg_mallocs()==-1)
		goto error00;

	init_route_lists();
	/* process command line (get port no, cfg. file path etc) */
	/* first reset getopt */
	optind = 1;
	while((c=getopt(argc,argv,options))!=-1){
		switch(c){
			case 'f':
					cfg_file=optarg;
					break;
			case 'C':
					config_check |= 2;
			case 'c':
					if (config_check==3)
						break;
					config_check |= 1;
					cfg_log_stderr=1; /* force stderr logging */
					break;
			case 'm':
					shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
					if (tmp &&(*tmp)){
						LM_ERR("bad shmem size number: -m %s\n", optarg);
						goto error00;
					};

					break;
			case 'M':
					/* ignoring it, parsed previously */

					break;
			case 'b':
					maxbuffer=strtol(optarg, &tmp, 10);
					if (tmp &&(*tmp)){
						LM_ERR("bad max buffer size number: -b %s\n", optarg);
						goto error00;
					}
					break;
			case 'l':
					if (parse_phostport(optarg, strlen(optarg), &tmp, &tmp_len,
											&port, &proto)<0){
						LM_ERR("bad -l address specifier: %s\n", optarg);
						goto error00;
					}
					tmp[tmp_len]=0; /* null terminate the host */
					/* add a new addr. to our address list */
					if (add_listen_iface(tmp, port, proto, 0, 0, 0,0 )!=0){
						LM_ERR("failed to add new listen address\n");
						goto error00;
					}
					break;
			case 'n':
					children_no=strtol(optarg, &tmp, 10);
					if ((tmp==0) ||(*tmp)){
						LM_ERR("bad process number: -n %s\n", optarg);
						goto error00;
					}
					break;
			case 'v':
					check_via=1;
					break;
			case 'r':
					received_dns|=DO_DNS;
					break;
			case 'R':
					received_dns|=DO_REV_DNS;
			case 'd':
#ifdef CHANGEABLE_DEBUG_LEVEL
					(*debug)++;
#else
					debug++;
#endif
					break;
			case 'D':
					dont_fork=1;
					break;
			case 'E':
					cfg_log_stderr=1;
					break;
			case 'T':
#ifdef USE_TCP
					tcp_disable=1;
#else
					LM_WARN("tcp support not compiled in\n");
#endif
					break;
			case 'S':
#ifdef USE_SCTP
					sctp_disable=1;
#else
					LM_WARN("sctp support not compiled in\n");
#endif
			break;
			case 'N':
#ifdef USE_TCP
					tcp_children_no=strtol(optarg, &tmp, 10);
					if ((tmp==0) ||(*tmp)){
						LM_ERR("bad process number: -N %s\n", optarg);
						goto error00;
					}
#else
					LM_WARN("tcp support not compiled in\n");
#endif
					break;
			case 'W':
#ifdef USE_TCP
					tcp_poll_method=get_poll_type(optarg);
					if (tcp_poll_method==POLL_NONE){
						LM_ERR("bad poll method name: -W %s\ntry "
							"one of %s.\n", optarg, poll_support);
						goto error00;
					}
#else
					LM_WARN("tcp support not compiled in\n");
#endif
					break;
			case 'V':
					printf("version: %s\n", version);
					printf("flags: %s\n", flags );
					print_ct_constants();
					printf("%s\n",id);
					printf("%s compiled on %s with %s\n", __FILE__,
							compiled, COMPILER );
					
					exit(0);
					break;
			case 'h':
					printf("version: %s\n", version);
					printf("%s",help_msg);
					exit(0);
					break;
			case 'w':
					working_dir=optarg;
					break;
			case 't':
					chroot_dir=optarg;
					break;
			case 'u':
					user=optarg;
					break;
			case 'g':
					group=optarg;
					break;
			case 'P':
					pid_file=optarg;
					break;
			case 'G':
					pgid_file=optarg;
					break;
			case 'o':
					if (add_arg_var(optarg) < 0)
						LM_ERR("cannot add option %s\n", optarg);
					break;
			case '?':
					if (isprint(optopt))
						LM_ERR("Unknown option `-%c`.\n", optopt);
					else
						LM_ERR("Unknown option character `\\x%x`.\n", optopt);
					goto error00;
			case ':':
					LM_ERR("Option `-%c` requires an argument.\n", optopt);
					goto error00;
			default:
					abort();
		}
	}

	log_stderr = cfg_log_stderr;

	/* fill missing arguments with the default values*/
	if (cfg_file==0) cfg_file=CFG_FILE;

	/* load config file or die */
	cfg_stream=fopen (cfg_file, "r");
	if (cfg_stream==0){
		LM_ERR("loading config file(%s): %s\n", cfg_file,
				strerror(errno));
		goto error00;
	}

	/* seed the prng, try to use /dev/urandom if possible */
	/* no debugging information is logged, because the standard
	   log level prior the config file parsing is L_NOTICE */
	seed=0;
	if ((rfd=open("/dev/urandom", O_RDONLY))!=-1){
try_again:
		if (read(rfd, (void*)&seed, sizeof(seed))==-1){
			if (errno==EINTR) goto try_again; /* interrupted by signal */
			LM_WARN("could not read from /dev/urandom (%d)\n", errno);
		}
		LM_DBG("initialize the pseudo random generator from "
			"/dev/urandom\n");
		LM_DBG("read %u from /dev/urandom\n", seed);
			close(rfd);
	}else{
		LM_WARN("could not open /dev/urandom (%d)\n", errno);
		LM_WARN("using a unsafe seed for the pseudo random number generator");
	}
	seed+=getpid()+time(0);
	LM_DBG("seeding PRNG with %u\n", seed);
	srand(seed);
	LM_DBG("test random number %u\n", rand());

	/*register builtin  modules*/
	register_builtin_modules();

#ifdef USE_TLS
	/* initialize default TLS domains,
	   must be done before reading the config */
	if (pre_init_tls()<0){
		LM_CRIT("could not pre_init_tls, exiting...\n");
		goto error00;
	}
#endif /* USE_TLS */

	if (preinit_black_lists()!=0) {
		LM_CRIT("failed to alloc black list's anchor\n");
		goto error00;
	}

	/* init avps */
	if (init_global_avps() != 0) {
		LM_ERR("error while initializing avps\n");
		goto error;
	}


	/* parse the config file, prior to this only default values
	   e.g. for debugging settings will be used */
	yyin=cfg_stream;
	if ((yyparse()!=0)||(cfg_errors)){
		LM_ERR("bad config file (%d errors)\n", cfg_errors);
		goto error00;
	}

	if (config_check>1 && check_rls()!=0) {
		LM_ERR("bad function call in config file\n");
		return ret;
	}
#ifdef EXTRA_DEBUG
	print_rl();
#endif

	/* init the resolver, before fixing the config */
	resolv_init();

	/* fix parameters */
	if (port_no<=0) port_no=SIP_PORT;
#ifdef USE_TLS
	if (tls_port_no<=0) tls_port_no=SIPS_PORT;
#endif
	
	
	if (children_no<=0) children_no=CHILD_NO;
#ifdef USE_TCP
	if (!tcp_disable){
		if (tcp_children_no<=0) tcp_children_no=children_no;
	}
#endif
	
	if (working_dir==0) working_dir="/";

	/* get uid/gid */
	if (user){
		if (user2uid(&uid, &gid, user)<0){
			LM_ERR("bad user name/uid number: -u %s\n", user);
			goto error00;
		}
	}
	if (group){
		if (group2gid(&gid, group)<0){
			LM_ERR("bad group name/gid number: -u %s\n", group);
			goto error00;
		}
	}
	if (fix_all_socket_lists()!=0){
		LM_ERR("failed to initialize list addresses\n");
		goto error00;
	}
	/* print all the listen addresses */
	printf("Listening on \n");
	print_all_socket_lists();
	printf("Aliases: \n");
	/*print_aliases();*/
	print_aliases();
	printf("\n");
	
	if (dont_fork){
		LM_WARN("no fork mode %s\n", 
				(udp_listen)?(
				(udp_listen->next)?" and more than one listen address found"
				"(will use only the first one)":""
				):"and no udp listen address found" );
	}
	if (config_check){
		LM_NOTICE("config file ok, exiting...\n");
		return 0;
	}


	time(&startup_time);

	/*init shm mallocs
	 *  this must be here 
	 *     -to allow setting shm mem size from the command line
	 *       => if shm_mem should be settable from the cfg file move
	 *       everything after
	 *     -it must be also before init_timer and init_tcp
	 *     -it must be after we know uid (so that in the SYSV sems case,
	 *        the sems will have the correct euid)
	 * --andrei */
	if (init_shm_mallocs()==-1)
		goto error;
	/*init timer, before parsing the cfg!*/
	if (init_timer()<0){
		LM_CRIT("could not initialize timer, exiting...\n");
		goto error;
	}
	
#ifdef USE_TCP
	if (!tcp_disable){
		/*init tcp*/
		if (init_tcp()<0){
			LM_CRIT("could not initialize tcp, exiting...\n");
			goto error;
		}
	}
#ifdef USE_TLS
	if (!tls_disable){
		/* init tls*/
		if (init_tls()<0){
			LM_CRIT("could not initialize tls, exiting...\n");
			goto error;
		}
	}
#endif /* USE_TLS */
#endif /* USE_TCP */

	/* init_daemon? */
	if (!dont_fork){
		if ( daemonize((log_name==0)?argv[0]:log_name, &own_pgid) <0 )
			goto error;
	}

	/* install signal handlers */
	if (install_sigs() != 0){
		LM_ERR("could not install the signal handlers\n");
		goto error;
	}

#ifdef CHANGEABLE_DEBUG_LEVEL
#ifdef SHM_MEM
	debug=shm_malloc(sizeof(int));
	if (debug==0) {
		LM_ERR("ERROR: out of memory\n");
		goto error;
	}
	*debug = debug_init;
#else
	LM_WARN("no shm mem support compiled -> changeable debug "
		"level turned off\n");
#endif
#endif

	if (disable_core_dump) set_core_dump(0, 0);
	else set_core_dump(1, shm_mem_size+pkg_mem_size+4*1024*1024);
	if (open_files_limit>0){
		if(increase_open_fds(open_files_limit)<0){ 
			LM_ERR("ERROR: error could not increase file limits\n");
			goto error;
		}
	}

	/* print OpenSIPS version to log for history tracking */
	LM_NOTICE("version: %s\n", version);
	
	/* print some data about the configuration */
#ifdef SHM_MEM
	LM_INFO("using %ld Mb shared memory\n", ((shm_mem_size/1024)/1024));
#endif
	LM_INFO("using %ld Mb private memory per process\n", ((pkg_mem_size/1024)/1024));

	/* init serial forking engine */
	if (init_serialization()!=0) {
		LM_ERR("failed to initialize serialization\n");
		goto error;
	}
	/* Init statistics */
	if (init_stats_collector()<0) {
		LM_ERR("failed to initialize statistics\n");
		goto error;
	}
	/* Init MI */
	if (init_mi_core()<0) {
		LM_ERR("failed to initialize MI core\n");
		goto error;
	}

	/* Register core events */
	if (evi_register_core() != 0) {
		LM_ERR("failed register core events\n");
		goto error;
	}

	/* init black list engine */
	if (init_black_lists()!=0) {
		LM_CRIT("failed to init black lists\n");
		goto error;
	}
	/* init resolver's blacklist */
	if (resolv_blacklist_init()!=0) {
		LM_CRIT("failed to create DNS blacklist\n");
		goto error;
	}

	/* init modules */
	if (init_modules() != 0) {
		LM_ERR("error while initializing modules\n");
		goto error;
	}

	/* register route timers */
	if(register_route_timers() < 0) {
		LM_ERR("Failed to register timer\n");
		goto error;
	}

	/* check pv context list */
	if(pv_contextlist_check() != 0) {
		LM_ERR("used pv context that was not defined\n");
		goto error;
	}

	/* init query list now in shm
	 * so all processes that will be forked from now on
	 * will have access to it 
	 *
	 * if it fails, give it a try and carry on */
	if (init_ql_support() != 0) {
		LM_ERR("failed to initialise buffering query list\n");
		query_buffer_size = 0;
		*query_list = NULL;
	}

	/* init multi processes support */
	if (init_multi_proc_support()!=0) {
		LM_ERR("failed to init multi-proc support\n");
		goto error;
	}

	#ifdef PKG_MALLOC
	/* init stats support for pkg mem */
	if (init_pkg_stats(counted_processes)!=0) {
		LM_ERR("failed to init stats for pkg\n");
		goto error;
	}
	#endif

	/* init avps */
	if (init_extra_avps() != 0) {
		LM_ERR("error while initializing avps\n");
		goto error;
	}

	/* fix routing lists */
	if ( (r=fix_rls())!=0){
		LM_ERR("failed to fix configuration with err code %d\n", r);
		goto error;
	};

	ret=main_loop();

error:

	/*kill everything*/
	kill_all_children(SIGTERM);
	/*clean-up*/
	cleanup(0);
error00:
	return ret;
}
Ejemplo n.º 5
0
/*
 * destroy function
 */
static void destroy(void)
{
	LM_NOTICE("destroy module cachedb_redis ...\n");
	cachedb_end_connections(&cache_mod_name);
	return;
}
Ejemplo n.º 6
0
int worker_reg_send_impl(ei_cnode *ec, int s,int wpid)
{
	str server = STR_NULL;
	ei_x_buff emsg;
	struct msghdr msgh;
	struct iovec cnt[6];
	int rc;

	memset((void*)&emsg,0,sizeof(emsg));

	memset((void*)&msgh,0,sizeof(msgh));

	/* server name length */
	cnt[0].iov_base = &server.len;
	cnt[0].iov_len  = sizeof(int);

	/* Erlang args size */
	cnt[1].iov_base = &emsg.buffsz;
	cnt[1].iov_len  = sizeof(int);

	/* get data size */
	msgh.msg_iov    = cnt;
	msgh.msg_iovlen = 2;

	while ((rc = recvmsg(s, &msgh, MSG_PEEK)) == -1 && errno == EAGAIN)
		;

	if (rc == -1){
		LM_ERR("recvmsg failed (socket=%d): %s\n",s,strerror(errno));
		return -1;
	}

	/* allocate space */
	server.s = (char*)pkg_malloc(server.len+1);
	if (!server.s) {
		LM_ERR("not enough memory\n");
		goto err;
	}

	emsg.buff = (char*)malloc(emsg.buffsz);
	if (!emsg.buff) {
		LM_ERR("malloc: not enough memory\n");
		goto err;
	}

	/* buffers */
	cnt[2].iov_base = server.s;
	cnt[2].iov_len  = server.len;

	cnt[3].iov_base = emsg.buff;
	cnt[3].iov_len  = emsg.buffsz;

	/* get whole data */
	msgh.msg_iovlen = 4;
	while ((rc = recvmsg(s, &msgh, MSG_WAITALL)) == -1 && errno == EAGAIN)
		;

	if (rc == -1){
		LM_ERR("recvmsg failed (socket=%d): %s\n",s,strerror(errno));
		goto err;
	}

	/* fix str */
	server.s[server.len] = 0;

	if(!enode) {
		LM_NOTICE("there is no connected Erlang node\n");
		goto err;
	}

	LM_DBG(">> {%.*s,'%s'} ! emsg\n",STR_FMT(&server),enode->conn.nodename);

	EI_X_BUFF_PRINT(&emsg);

	/* do ERL_REG_SEND */
	if ((rc = ei_reg_send(ec,enode->sockfd,server.s,emsg.buff,emsg.buffsz)) == ERL_ERROR)
	{
		if (erl_errno)
		{
			LM_ERR("ei_reg_send failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(erl_errno));
		}
		else if (errno)
		{
			LM_ERR("ei_reg_send failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(errno));
		}
		else
		{
			LM_ERR("ei_reg_send failed on node=<%s> socket=<%d>, Unknown error.\n",ec->thisalivename,enode->sockfd);
		}
	}

	pkg_free(server.s);
	free(emsg.buff);

	return 0;

err:
	pkg_free(server.s);
	free(emsg.buff);

	return -1;
}
Ejemplo n.º 7
0
void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents)
{
#define CLIENT_BUFFER_SIZE	4096
	char rbuffer[CLIENT_BUFFER_SIZE];
	ssize_t rlen;
	int i, k;
	evapi_env_t evenv;
	str frame;

	if(EV_ERROR & revents) {
		perror("received invalid event\n");
		return;
	}

	/* read message from client */
	rlen = recv(watcher->fd, rbuffer, CLIENT_BUFFER_SIZE-1, 0);

	if(rlen < 0) {
		LM_ERR("cannot read the client message\n");
		return;
	}

	for(i=0; i<EVAPI_MAX_CLIENTS; i++) {
		if(_evapi_clients[i].connected==1 && _evapi_clients[i].sock==watcher->fd) {
			break;
		}
	}
	if(i==EVAPI_MAX_CLIENTS) {
		LM_ERR("cannot lookup client socket %d\n", watcher->fd);
		return;
	}

	evapi_env_reset(&evenv);
	if(rlen == 0) {
		/* client is gone */
		evenv.eset = 1;
		evenv.conidx = i;
		evapi_run_cfg_route(&evenv, _evapi_rts.con_closed);
		_evapi_clients[i].connected = 0;
		_evapi_clients[i].sock = 0;
		ev_io_stop(loop, watcher);
		free(watcher);
		LM_INFO("client closing connection - pos [%d] addr [%s:%d]\n",
				i, _evapi_clients[i].src_addr, _evapi_clients[i].src_port);
		return;
	}

	rbuffer[rlen] = '\0';

	LM_NOTICE("{%d} [%s:%d] - received [%.*s]\n",
			i, _evapi_clients[i].src_addr, _evapi_clients[i].src_port,
			(int)rlen, rbuffer);
	evenv.conidx = i;
	evenv.eset = 1;
	if(_evapi_netstring_format) {
		/* netstring decapsulation */
		k = 0;
		while(k<rlen) {
			frame.len = 0;
			while(k<rlen) {
				if(rbuffer[k]==' ' || rbuffer[k]=='\t'
						|| rbuffer[k]=='\r' || rbuffer[k]=='\n')
					k++;
				else break;
			}
			if(k==rlen) return;
			while(k<rlen) {
				if(rbuffer[k]>='0' && rbuffer[k]<='9') {
					frame.len = frame.len*10 + rbuffer[k] - '0';
				} else {
					if(rbuffer[k]==':')
						break;
					/* invalid character - discard the rest */
					return;
				}
				k++;
			}
			if(k==rlen || frame.len<=0) return;
			if(frame.len + k>=rlen) return;
			k++;
			frame.s = rbuffer + k;
			if(frame.s[frame.len]!=',') return;
			frame.s[frame.len] = '\0';
			k += frame.len ;
			evenv.msg.s = frame.s;
			evenv.msg.len = frame.len;
			evapi_run_cfg_route(&evenv, _evapi_rts.msg_received);
			k++;
		}
	} else {
		evenv.msg.s = rbuffer;
		evenv.msg.len = rlen;
		evapi_run_cfg_route(&evenv, _evapi_rts.msg_received);
	}
}
Ejemplo n.º 8
0
int pv_add_json ( pv_param_t* pvp, json_t * obj )
{
	json_t *dest;
	json_name * id;
	pv_json_t * var;
	json_tag * tag;
	int poz;


	id = (json_name *) pvp->pvn.u.dname;


	var = get_pv_json(pvp);

	if( var == NULL )
	{

		if( id->tags )
		{
			LM_ERR("Object is not initialized yet\n");
			return -1;
		}

		var = (pv_json_t *) pkg_malloc(sizeof(pv_json_t));

		if( var == NULL )
		{
			LM_ERR("Out of memory\n");
			return -1;
		}

		memset(var,0,sizeof(pv_json_t));

		var->name = id->name;
		var->next = all;

		var->data = obj;
		all = var;
		return 0;
	}


	if( id ->tags == NULL)
	{
		if( var->data )
			json_object_put(var->data);

		var->data = obj;
		return 0;
	}


	dest = get_object(var, pvp, &tag, 1);

	if( dest == NULL )
	{
		LM_NOTICE("Could not find object with that path\n");
		return -1;
	}

	if( tag->type & TAG_KEY )
	{
		memcpy(buff,tag->key.s,tag->key.len);
		buff[tag->key.len] = 0;

		if( obj == NULL )
			json_object_object_del(dest,buff);
		else
			json_object_object_add(dest,buff,obj);
	}

	if( tag->type & TAG_IDX )
	{

		poz = tag->idx;

		if( tag->type & TAG_END )
		{
			if( obj == NULL)
			{
				LM_ERR("Invalid parameter for deletion\n");
				return -1;
			}

			json_object_array_add(dest,obj);
			return 0;

		}

		if(  poz < 0 )
			poz += json_object_array_length(dest);




		if( poz<0 || poz >= json_object_array_length(dest))
		{
			LM_ERR("Attempting to replace at invalid index in array:%d\n",
				poz);
			return -1;
		}

		if( obj == NULL)
		{
			if( poz >= json_object_array_length(dest))
			{
				LM_ERR("Index out of bounds for deletion\n");
				return -1;
			}

			json_object_array_del(dest,poz);
		}
		else
			json_object_array_put_idx(dest,poz,obj);
	}

	return 0;

}
Ejemplo n.º 9
0
/* it checks if a user is member of a group */
int diameter_is_user_in(struct sip_msg* _m, char* _hf, char* _group)
{
	str *grp, user_name, user, domain, uri;
	dig_cred_t* cred = 0;
	int hf_type;
	struct hdr_field* h;
	struct sip_uri puri;
	AAAMessage *req;
	AAA_AVP *avp; 
	int ret;
	unsigned int tmp;

	grp = (str*)_group; /* via fixup */

	hf_type = (int)(long)_hf;

	uri.s = 0;
	uri.len = 0;

	/* extract the uri according with the _hf parameter */
	switch(hf_type) 
	{
		case 1: /* Request-URI */
			uri = *(GET_RURI(_m));
		break;

		case 2: /* To */
			if (get_to_uri(_m, &uri) < 0) 
			{
				LM_ERR("failed to extract To\n");
				return -2;
			}
			break;

		case 3: /* From */
			if (get_from_uri(_m, &uri) < 0) 
			{
				LM_ERR("failed to extract From URI\n");
				return -3;
			}
			break;

		case 4: /* Credentials */
			get_authorized_cred(_m->authorization, &h);
			if (!h) 	
			{
				get_authorized_cred(_m->proxy_auth, &h);
				if (!h) 
				{
					LM_ERR("no authorized credentials found "
							"(error in scripts)\n");
					return -4;
				}
			}
			cred = &((auth_body_t*)(h->parsed))->digest;
			break;
	}

	if (hf_type != 4) 
	{
		if (parse_uri(uri.s, uri.len, &puri) < 0) 
		{
			LM_ERR("failed to parse URI\n");
			return -5;
		}
		user = puri.user;
		domain = puri.host;
	} 
	else
	{
		user = cred->username.user;
		domain = cred->realm;
	}
	
	/* user@domain mode */
	if (use_domain)
	{
		user_name.s = 0;
		user_name.len = user.len + domain.len;
		if(user_name.len>0)
		{
			user_name.len++;
			user_name.s = (char*)pkg_malloc(user_name.len);
			if (!user_name.s) 
			{
				LM_ERR("no pkg memory left\n");
				return -6;
			}
		
			memcpy(user_name.s, user.s, user.len);
			if(user.len>0)
			{
				user_name.s[user.len] = '@';
				memcpy(user_name.s + user.len + 1, domain.s, domain.len);
			}
			else
				memcpy(user_name.s, domain.s, domain.len);
		}
	} 
	else 
		user_name = user;
	
	
	if ( (req=AAAInMessage(AA_REQUEST, AAA_APP_NASREQ))==NULL)
	{
		LM_ERR("can't create new AAA message!\n");
		return -1;
	}
	
	/* Username AVP */
	if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s,
				user_name.len, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}

	/* Usergroup AVP */
	if( (avp=AAACreateAVP(AVP_User_Group, 0, 0, grp->s,
				grp->len, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}

	/* SIP_MSGID AVP */
	LM_DBG("******* m_id=%d\n", _m->id);
	tmp = _m->id;
	if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&tmp), 
				sizeof(tmp), AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}

	
	/* ServiceType AVP */
	if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_GROUP_CHECK, 
				SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}
	

	/* Destination-Realm AVP */
	uri = *(GET_RURI(_m));
	parse_uri(uri.s, uri.len, &puri);
	if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s,
						puri.host.len, AVP_DUPLICATE_DATA)) == 0)
	{
		LM_ERR("no more pkg memory!\n");
		goto error;
	}
	
	if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
	{
		LM_ERR("avp not added \n");
		goto error1;
	}
	
#ifdef DEBUG
	AAAPrintMessage(req);
#endif

	/* build a AAA message buffer */
	if(AAABuildMsgBuffer(req) != AAA_ERR_SUCCESS)
	{
		LM_ERR("message buffer not created\n");
		goto error;
	}

	if(sockfd==AAA_NO_CONNECTION)
	{
		sockfd = init_mytcp(diameter_client_host, diameter_client_port);
		if(sockfd==AAA_NO_CONNECTION)
		{
			LM_ERR("failed to reconnect to Diameter client\n");
			goto error;
		}
	}

	ret =tcp_send_recv(sockfd, req->buf.s, req->buf.len, rb, _m->id);

	if(ret == AAA_CONN_CLOSED)
	{
		LM_NOTICE("connection to Diameter client closed."
				"It will be reopened by the next request\n");
		close(sockfd);
		sockfd = AAA_NO_CONNECTION;
		goto error;
	}
	if(ret != AAA_USER_IN_GROUP)
	{
		LM_ERR("message sending to the DIAMETER backend authorization server"
				"failed or user is not in group\n");
		goto error;
	}
	
	AAAFreeMessage(&req);
	return 1;

error1:
	AAAFreeAVP(&avp);
error:
	AAAFreeMessage(&req);
	return -1;

}
Ejemplo n.º 10
0
static int mod_init(void)
{
    JavaVMInitArgs  vm_args;
    jint res;
    JavaVMOption *options;
    char **opts;
    int nOptions;

    if (force_cmd_exec < 0 || force_cmd_exec > 1)
    {
	LM_ERR("Parameter force_cmd_exec should be either 0 or 1\n");
	return -1;
    }

    if (force_cmd_exec)
    {
	LM_NOTICE("%s: Parameter force_cmd_exec may cause a memory leaks if used from embedded languages\n", APP_NAME);
    }

    options = (JavaVMOption *)pkg_malloc(sizeof(JavaVMOption));
    if (!options)
    {
	LM_ERR("pkg_malloc() failed: Couldn't initialize Java VM: Not enough memory\n");
	return -1;
    }
    memset(options, 0, sizeof(JavaVMOption));

    LM_INFO("Initializing Java VM with options: %s\n", java_options_str.s);

    opts = split(java_options_str.s, " ");
    for (nOptions=0; opts[nOptions] != NULL; nOptions++)
    {
	options[nOptions].optionString = opts[nOptions];
    }

    /* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and beyond */
    vm_args.version = JNI_VERSION_1_2;
    vm_args.nOptions = nOptions;
    vm_args.ignoreUnrecognized = JNI_FALSE;
    vm_args.options = options;

    res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
    if (res < 0)
    {
	handle_VM_init_failure(res);
	return -1;
    }

    LM_INFO("%s: Java VM initialization OK\n", APP_NAME);

    // attach to current thread
    (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
    if ((*env)->ExceptionCheck(env))
    {
	handle_exception();
	return -1;
    }

    KamailioClass = (*env)->FindClass(env, class_name.s);
    if (!KamailioClass || (*env)->ExceptionCheck(env))
    {
	handle_exception();
	(*jvm)->DetachCurrentThread(jvm);
	return -1;
    }

    KamailioClassRef = (*env)->NewGlobalRef(env, KamailioClass);
    if (!KamailioClassRef || (*env)->ExceptionCheck(env))
    {
	handle_exception();
	(*jvm)->DetachCurrentThread(jvm);
	return -1;
    }

    KamailioID = (*env)->GetMethodID(env, KamailioClass, "<init>", "()V");
    if (!KamailioID || (*env)->ExceptionCheck(env))
    {
	handle_exception();
	(*jvm)->DetachCurrentThread(jvm);
	return -1;
    }

    // calling constructor
    KamailioClassInstance = (*env)->NewObject(env, KamailioClass, KamailioID);
    if (!KamailioClassInstance || (*env)->ExceptionCheck(env))
    {
	handle_exception();
	(*jvm)->DetachCurrentThread(jvm);
	return -1;
    }

    // keep a reference to kamailio class instance
    KamailioClassInstanceRef = (*env)->NewGlobalRef(env, KamailioClassInstance);
    if (!KamailioClassInstanceRef || (*env)->ExceptionCheck(env))
    {
	handle_exception();
	(*jvm)->DetachCurrentThread(jvm);
	return -1;
    }

    LM_INFO("%s: module initialization OK\n", APP_NAME);

    if (jvm != NULL)
        (*jvm)->DetachCurrentThread(jvm);

    return 0;
}
Ejemplo n.º 11
0
json_t * get_object(pv_json_t * var, pv_param_t* pvp ,  json_tag ** tag,
			int report_err )
{
	json_name * id = (json_name *) pvp->pvn.u.dname;

	json_t * cur_obj, * last_obj = 0;
	json_tag * cur_tag, * last_tag = 0;
	int poz;



	cur_tag = id->tags;
	cur_obj = var->data;


	while( cur_tag  )
	{
		last_tag = cur_tag;
		last_obj = cur_obj;

		if( cur_tag->type & TAG_KEY )
		{
			memcpy( buff, cur_tag->key.s, cur_tag->key.len );
			buff[cur_tag->key.len] = 0;

			if( cur_obj == NULL ||
				!json_object_is_type( cur_obj, json_type_object ) )
				goto error;

#if JSON_LIB_VERSION < 10
			cur_obj = json_object_object_get( cur_obj, buff );

			if( cur_obj == NULL && tag == NULL)
				goto error;
#else
			if (!json_object_object_get_ex( cur_obj,buff, &cur_obj ) &&
				tag == NULL)
				goto error;
#endif



		}

		if( cur_tag->type & TAG_IDX )
		{

			if( cur_obj == NULL ||
				!json_object_is_type( cur_obj, json_type_array ) )
				goto error;


			poz = cur_tag->idx;

			if( cur_tag->type & TAG_END )
			{
				poz = json_object_array_length(cur_obj);
			}
			else
			{
				if( poz < 0 )
					poz += json_object_array_length(cur_obj);
			}


			if( poz < 0 )
				goto error;

			cur_obj = json_object_array_get_idx( cur_obj, poz );

			if( cur_obj == NULL && tag == NULL)
				goto error;

		}

		cur_tag = cur_tag->next;
	}

	if( tag == NULL )
	{
		return cur_obj;
	}
	else
	{
		*tag = last_tag;
		return last_obj;
	}

error:

	if( report_err)
	{
		LM_NOTICE("Trying to get a value from a json of incorrect type\n");
		if(var->data)
			LM_NOTICE("Object is:\n%s\n",
				json_object_to_json_string(var->data));
		else
			LM_NOTICE("Object is null\n");
		print_tag_list( id->tags, cur_tag->next, 1);
	}

	return NULL;

}
Ejemplo n.º 12
0
static int backup_config(void) {
	FILE * from, * to;
	char * backup_file, ch;
	LM_INFO("start configuration backup\n");
	if((backup_file = pkg_malloc(strlen(config_file) + strlen (".bak") + 1)) == NULL){
		PKG_MEM_ERROR;
		return -1;
	}
	if(!strcpy(backup_file, config_file)){
		LM_ERR("can't copy filename\n");
		goto errout;
	}
	if(!strcat(backup_file, ".bak")){
		LM_ERR("can't attach suffix\n");
		goto errout;
	}
	/* open source file */
	if ((from = fopen(config_file, "rb"))==NULL) {
		LM_ERR("Cannot open source file.\n");
		goto errout;
	}

	/* open destination file */
	if ((to = fopen(backup_file, "wb"))==NULL) {
		LM_ERR("Cannot open destination file.\n");
		fclose(from);
		goto errout;
	}

	/* copy the file */
	while (!feof(from)) {
		ch = fgetc(from);
		if (ferror(from)) {
			LM_ERR("Error reading source file.\n");
			goto errclose;
		}
		if (!feof(from)) fputc(ch, to);
		if (ferror(to)) {
			LM_ERR("Error writing destination file.\n");
			goto errclose;
		}
	}

	if (fclose(from)==EOF) {
		LM_ERR("Error closing source file.\n");
		fclose(to);
		goto errout;
	}

	if (fclose(to)==EOF) {
		LM_ERR("Error closing destination file.\n");
		goto errout;
	}
	LM_NOTICE("backup written to %s\n", backup_file);
	pkg_free(backup_file);
	return 0;
errclose:
	/* close the files so that resource leak is prevented ; ignore errors*/
	fclose(from);
	fclose(to);
errout:
	pkg_free(backup_file);
	return -1;
}
Ejemplo n.º 13
0
/*!
 * \brief Load all records from a udomain
 *
 * Load all records from a udomain, useful to populate the
 * memory cache on startup.
 * \param _c database connection
 * \param _d loaded domain
 * \return 0 on success, -1 on failure
 */
int preload_udomain(db1_con_t* _c, udomain_t* _d)
{
	pcontact_info_t *ci;
	db_row_t *row;
	db_key_t columns[18];
	db1_res_t* res = NULL;
	str aor, contact;
	int i, n;

	pcontact_t* c;

	LM_DBG("pre-loading domain from DB\n");

	columns[0] = &domain_col;
	columns[1] = &aor_col;
	columns[2] = &contact_col;
	columns[3] = &received_col;
	columns[4] = &rx_session_id_col;
	columns[5] = &reg_state_col;
	columns[6] = &expires_col;
	columns[7] = &socket_col;
	columns[8] = &service_routes_col;
	columns[9] = &public_ids_col;
	columns[10] = &path_col;

	if (ul_dbf.use_table(_c, _d->name) < 0) {
		LM_ERR("sql use_table failed\n");
		return -1;
	}

#ifdef EXTRA_DEBUG
	LM_NOTICE("load start time [%d]\n", (int)time(NULL));
#endif

	if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
		if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 11, 0, 0) < 0) {
			LM_ERR("db_query (1) failed\n");
			return -1;
		}
		if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
			LM_ERR("fetching rows failed\n");
			return -1;
		}
	} else {
		if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 11, 0, &res) < 0) {
			LM_ERR("db_query failed\n");
			return -1;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("table is empty\n");
		ul_dbf.free_result(_c, res);
		return 0;
	}

	LM_DBG("%d rows returned in preload\n", RES_ROW_N(res));

	n = 0;
	do {
		LM_DBG("loading records - cycle [%d]\n", ++n);
		for(i = 0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;

			aor.s = (char*) VAL_STRING(ROW_VALUES(row) + 1);
			if (VAL_NULL(ROW_VALUES(row) + 1) || aor.s == 0 || aor.s[0] == 0) {
				LM_CRIT("empty aor record in table %s...skipping\n", _d->name->s);
				continue;
			}
			aor.len = strlen(aor.s);

			ci = dbrow2info( ROW_VALUES(row)+1, &contact);
			if (ci==0) {
				LM_ERR("usrloc record for %.*s in table %s\n",
						aor.len, aor.s, _d->name->s);
				continue;
			}
			lock_udomain(_d, &aor);

			if ( (mem_insert_pcontact(_d, &aor, ci, &c)) != 0) {
				LM_ERR("inserting contact failed\n");
				unlock_udomain(_d, &aor);
				goto error1;
			}
			unlock_udomain(_d, &aor);
		}

		if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
			if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
				LM_ERR("fetching rows (1) failed\n");
				ul_dbf.free_result(_c, res);
				return -1;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	ul_dbf.free_result(_c, res);

#ifdef EXTRA_DEBUG
	LM_NOTICE("load end time [%d]\n", (int)time(NULL));
#endif

	return 0;
error1:
	free_pcontact(c);

	ul_dbf.free_result(_c, res);
	return -1;
}
Ejemplo n.º 14
0
/** Receive message
 *  WARNING: buf must be 0 terminated (buf[len]=0) or some things might
 * break (e.g.: modules/textops)
 */
int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
{
	struct sip_msg* msg;
	struct run_act_ctx ctx;
	struct run_act_ctx *bctx;
	int ret;
#ifdef STATS
	int skipped = 1;
	int stats_on = 1;
#else
	int stats_on = 0;
#endif
	struct timeval tvb, tve;
	struct timezone tz;
	unsigned int diff = 0;
	str inb;
	sr_net_info_t netinfo;
	sr_kemi_eng_t *keng = NULL;

	if(sr_event_enabled(SREV_NET_DATA_RECV)) {
		if(sip_check_fline(buf, len)==0) {
			memset(&netinfo, 0, sizeof(sr_net_info_t));
			netinfo.data.s = buf;
			netinfo.data.len = len;
			netinfo.rcv = rcv_info;
			sr_event_exec(SREV_NET_DATA_RECV, (void*)&netinfo);
		}
	}

	inb.s = buf;
	inb.len = len;
	sr_event_exec(SREV_NET_DATA_IN, (void*)&inb);
	len = inb.len;

	msg=pkg_malloc(sizeof(struct sip_msg));
	if (msg==0) {
		LM_ERR("no mem for sip_msg\n");
		goto error00;
	}
	msg_no++;
	/* number of vias parsed -- good for diagnostic info in replies */
	via_cnt=0;

	memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
	/* fill in msg */
	msg->buf=buf;
	msg->len=len;
	/* zero termination (termination of orig message bellow not that
	 * useful as most of the work is done with scratch-pad; -jiri  */
	/* buf[len]=0; */ /* WARNING: zero term removed! */
	msg->rcv=*rcv_info;
	msg->id=msg_no;
	msg->pid=my_pid();
	msg->set_global_address=default_global_address;
	msg->set_global_port=default_global_port;

	if(likely(sr_msg_time==1)) msg_set_time(msg);

	if (parse_msg(buf,len, msg)!=0){
		if((ret=sr_event_exec(SREV_RCV_NOSIP, (void*)msg))<NONSIP_MSG_DROP) {
			LOG(cfg_get(core, core_cfg, corelog),
				"core parsing of SIP message failed (%s:%d/%d)\n",
				ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
				(int)msg->rcv.proto);
			sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
		}
		else if(ret == NONSIP_MSG_DROP) goto error02;
	}

	parse_headers(msg, HDR_FROM_F|HDR_TO_F|HDR_CALLID_F|HDR_CSEQ_F, 0);
	LM_DBG("--- received sip message - %s - call-id: [%.*s] - cseq: [%.*s]\n",
			(msg->first_line.type==SIP_REQUEST)?"request":"reply",
			(msg->callid && msg->callid->body.s)?msg->callid->body.len:0,
			(msg->callid && msg->callid->body.s)?msg->callid->body.s:"",
			(msg->cseq && msg->cseq->body.s)?msg->cseq->body.len:0,
			(msg->cseq && msg->cseq->body.s)?msg->cseq->body.s:"");

	/* set log prefix */
	log_prefix_set(msg);

	/* ... clear branches from previous message */
	clear_branches();

	if (msg->first_line.type==SIP_REQUEST){
		ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
		if (!IS_SIP(msg)){
			if ((ret=nonsip_msg_run_hooks(msg))!=NONSIP_MSG_ACCEPT){
				if (unlikely(ret==NONSIP_MSG_ERROR))
					goto error03;
				goto end; /* drop the message */
			}
		}
		/* sanity checks */
		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
			/* no via, send back error ? */
			LM_ERR("no via found in request\n");
			STATS_BAD_MSG();
			goto error02;
		}
		/* check if necessary to add receive?->moved to forward_req */
		/* check for the alias stuff */
#ifdef USE_TCP
		if (msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases) &&
				(((rcv_info->proto==PROTO_TCP) && !tcp_disable)
#ifdef USE_TLS
					|| ((rcv_info->proto==PROTO_TLS) && !tls_disable)
#endif
				)
			){
			if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
									rcv_info->proto)!=0){
				LM_ERR("tcp alias failed\n");
				/* continue */
			}
		}
#endif

	/*	skip: */
		LM_DBG("preparing to run routing scripts...\n");
		if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
				|| stats_on==1) {
			gettimeofday( & tvb, &tz );
		}
		/* execute pre-script callbacks, if any; -jiri */
		/* if some of the callbacks said not to continue with
		 * script processing, don't do so
		 * if we are here basic sanity checks are already done
		 * (like presence of at least one via), so you can count
		 * on via1 being parsed in a pre-script callback --andrei
		*/
		if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
		{
			STATS_REQ_FWD_DROP();
			goto end; /* drop the request */
		}

		set_route_type(REQUEST_ROUTE);
		/* exec the routing script */
		if(unlikely(main_rt.rlist[DEFAULT_RT]==NULL)) {
			keng = sr_kemi_eng_get();
			if(keng==NULL) {
				LM_ERR("no config routing engine registered\n");
				goto error_req;
			}
			if(keng->froute(msg, REQUEST_ROUTE, NULL, NULL)<0) {
				LM_NOTICE("negative return code from engine function\n");
			}
		} else {
			if (run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0)<0){
				LM_WARN("error while trying script\n");
				goto error_req;
			}
		}

		if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
				|| stats_on==1) {
			gettimeofday( & tve, &tz );
			diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
			LOG(cfg_get(core, core_cfg, latency_cfg_log),
					"request-route executed in: %d usec\n", diff);
#ifdef STATS
			stats->processed_requests++;
			stats->acc_req_time += diff;
			STATS_RX_REQUEST( msg->first_line.u.request.method_value );
#endif
		}

		/* execute post request-script callbacks */
		exec_post_script_cb(msg, REQUEST_CB_TYPE);
	}else if (msg->first_line.type==SIP_REPLY){
		/* sanity checks */
		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
			/* no via, send back error ? */
			LM_ERR("no via found in reply\n");
			STATS_BAD_RPL();
			goto error02;
		}

		if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
				|| stats_on==1) {
			gettimeofday( & tvb, &tz );
		}
#ifdef STATS
		STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
#endif

		/* execute pre-script callbacks, if any; -jiri */
		/* if some of the callbacks said not to continue with
		 * script processing, don't do so
		 * if we are here basic sanity checks are already done
		 * (like presence of at least one via), so you can count
		 * on via1 being parsed in a pre-script callback --andrei
		*/
		if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
		{
			STATS_RPL_FWD_DROP();
			goto end; /* drop the reply */
		}

		/* exec the onreply routing script */
		keng = sr_kemi_eng_get();
		if (onreply_rt.rlist[DEFAULT_RT]!=NULL || keng!=NULL){
			set_route_type(CORE_ONREPLY_ROUTE);
			ret = 1;
			if(unlikely(keng!=NULL)) {
				bctx = sr_kemi_act_ctx_get();
				init_run_actions_ctx(&ctx);
				sr_kemi_act_ctx_set(&ctx);
				ret = keng->froute(msg, CORE_ONREPLY_ROUTE, NULL, NULL);
				sr_kemi_act_ctx_set(bctx);
			} else {
				ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
			}
#ifndef NO_ONREPLY_ROUTE_ERROR
			if (unlikely(ret<0)){
				LM_WARN("error while trying onreply script\n");
				goto error_rpl;
			}else
#endif /* NO_ONREPLY_ROUTE_ERROR */
			if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
				STATS_RPL_FWD_DROP();
				goto skip_send_reply; /* drop the message, no error */
			}
		}
		/* send the msg */
		forward_reply(msg);
	skip_send_reply:
		if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))
				|| stats_on==1) {
			gettimeofday( & tve, &tz );
			diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
			LOG(cfg_get(core, core_cfg, latency_cfg_log),
					"reply-route executed in: %d usec\n", diff);
#ifdef STATS
			stats->processed_responses++;
			stats->acc_res_time+=diff;
#endif
		}

		/* execute post reply-script callbacks */
		exec_post_script_cb(msg, ONREPLY_CB_TYPE);
	}

end:
#ifdef STATS
	skipped = 0;
#endif
	/* free possible loaded avps -bogdan */
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
	LM_DBG("cleaning up\n");
	free_sip_msg(msg);
	pkg_free(msg);
#ifdef STATS
	if (skipped) STATS_RX_DROPS;
#endif
	/* reset log prefix */
	log_prefix_set(NULL);
	return 0;

#ifndef NO_ONREPLY_ROUTE_ERROR
error_rpl:
	/* execute post reply-script callbacks */
	exec_post_script_cb(msg, ONREPLY_CB_TYPE);
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
	goto error02;
#endif /* NO_ONREPLY_ROUTE_ERROR */
error_req:
	LM_DBG("error:...\n");
	/* execute post request-script callbacks */
	exec_post_script_cb(msg, REQUEST_CB_TYPE);
error03:
	/* free possible loaded avps -bogdan */
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
error02:
	free_sip_msg(msg);
	pkg_free(msg);
error00:
	STATS_RX_DROPS;
	/* reset log prefix */
	log_prefix_set(NULL);
	return -1;
}
Ejemplo n.º 15
0
int _impl_api_rpc_call(ei_x_buff *reply, const str *module,const str *function, const ei_x_buff *args)
{
	struct msghdr msgh;
	struct iovec cnt[8];
	int pid_no = my_pid();
	eapi_t api = API_RPC_CALL;
	int buffsz=0;
	int rc;

	if (!csockfd) {

		if (!enode) {
			LM_NOTICE("there is no connected Erlang node\n");
			/* reply up with error */
			ei_x_format(reply, "{error,cnode,~a}", "no_erlang_node");
			return -1;
		}

		if (rex_call_in_progress) {
			LM_ERR("RPC loop detected\n");
			ei_x_format(reply, "{badrpc,cnode,~a}", "rpc_loop_detected");
			return -1;
		}

		/* do RPC from event route */
		if (ei_rpc(&enode->ec,enode->sockfd,module->s,function->s,args->buff,args->index,reply) == ERL_ERROR)
		{
			reply->index = 0; /* re-use reply buffer */

			if (erl_errno)
			{
				ei_x_format(reply, "{error,cnode,~s}", strerror(erl_errno));
				LM_ERR("ei_rpc failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(erl_errno));
			}
			else if (errno)
			{
				ei_x_format(reply, "{error,cnode,~s}", strerror(errno));
				LM_ERR("ei_rpc failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(errno));
			}
			else
			{
				ei_x_format(reply, "{error,cnode,~s}", "Unknown error.");
				LM_ERR("ei_rpc failed on node=<%s> socket=<%d>, Unknown error.\n",enode->ec.thisalivename,enode->sockfd);
			}
			return -1;
		}
		/* reset response */
		enode->response.index = 0;
		return 0;
	}

	memset(&msgh, 0, sizeof(msgh));
	memset(&cnt, 0, sizeof(cnt));

	/* Kamailio PID */
	cnt[0].iov_base = (void*)&pid_no;
	cnt[0].iov_len  = sizeof(pid_no);

	/* method */
	cnt[1].iov_base = (void*)&api;
	cnt[1].iov_len = sizeof(api);

	/* put size of following data */
	cnt[2].iov_base = (void*)&module->len;
	cnt[2].iov_len  = sizeof(int);

	cnt[3].iov_base = (void*)&function->len;
	cnt[3].iov_len  = sizeof(int);

	buffsz = args->index; /* occupied size */
	cnt[4].iov_base = (void*) &buffsz;
	cnt[4].iov_len = sizeof(buffsz);

	/* module name */
	cnt[5].iov_base = (void*)module->s;
	cnt[5].iov_len  = module->len;

	/* function name */
	cnt[6].iov_base = (void*)function->s;
	cnt[6].iov_len  = function->len;

	/* Erlang arguments content */
	cnt[7].iov_base = (void*)args->buff;
	cnt[7].iov_len = buffsz; /* occupied size */

	msgh.msg_iov = cnt;
	msgh.msg_iovlen = 8;

	while ((rc = sendmsg(csockfd, &msgh, 0)) == -1 && errno == EAGAIN)
		;

	if (rc == -1) {
		LM_ERR("sendmsg failed: %s\n",strerror(errno));
		return -1;
	}

	/*receive into reply buffer */
	cnt[1].iov_base = &buffsz;
	cnt[1].iov_len  = sizeof(buffsz);

	/* peek reply size safe */
	msgh.msg_iovlen = 2;
	while ((rc = recvmsg(csockfd, &msgh, MSG_PEEK)) == -1 && errno == EAGAIN)
		;

	if (rc == -1) {
		LM_ERR("recvmsg failed: %s\n",strerror(errno));
		return -1;
	}

	if (reply->buffsz < buffsz) {
		ei_x_free(reply);
		reply->buffsz = buffsz + 1;
		reply->buff = (char*)malloc(reply->buffsz);
	}

	cnt[2].iov_base = (void*)reply->buff;
	cnt[2].iov_len  = buffsz;

	msgh.msg_iovlen = 3;
	while ((rc = recvmsg(csockfd, &msgh, MSG_WAITALL)) == -1 && errno == EAGAIN)
		;

	if (rc == -1) {
		LM_ERR("recvmsg failed: %s\n",strerror(errno));
		return -1;
	}

	if(pid_no != my_pid()) {
		/* should never happened */
		LM_CRIT("BUG: got other process reply (pid_no=%d)\n",pid_no);
		return -1;
	}

	return 0;
}
Ejemplo n.º 16
0
/* This callback is called during each verification process,
   at each step during the chain of certificates (this function
   is not the certificate_verification one!). */
int verify_callback(int pre_verify_ok, X509_STORE_CTX *ctx) {
	char buf[256];
	X509 *err_cert;
	int err, depth;

	depth = X509_STORE_CTX_get_error_depth(ctx);
	LM_NOTICE("depth = %d\n",depth);
	if ( depth > VERIFY_DEPTH_S ) {
		LM_NOTICE("cert chain too long ( depth > VERIFY_DEPTH_S)\n");
		pre_verify_ok=0;
	}

	if( pre_verify_ok ) {
		LM_NOTICE("preverify is good: verify return: %d\n", pre_verify_ok);
		return pre_verify_ok;
	}

	err_cert = X509_STORE_CTX_get_current_cert(ctx);
	err = X509_STORE_CTX_get_error(ctx);
	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);

	LM_NOTICE("subject = %s\n", buf);
	LM_NOTICE("verify error:num=%d:%s\n",
			err, X509_verify_cert_error_string(err));
	LM_NOTICE("error code is %d\n", ctx->error);

	switch (ctx->error) {
		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
			X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),
					buf,sizeof buf);
			LM_NOTICE("issuer= %s\n",buf);
			break;
		case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
		case X509_V_ERR_CERT_NOT_YET_VALID:
			LM_NOTICE("notBefore\n");
			break;
		case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
		case X509_V_ERR_CERT_HAS_EXPIRED:
			LM_NOTICE("notAfter\n");
			break;
		case X509_V_ERR_CERT_SIGNATURE_FAILURE:
		case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
			LM_NOTICE("unable to decrypt cert "
					"signature\n");
			break;
		case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
			LM_NOTICE("unable to decode issuer "
					"public key\n");
			break;
		case X509_V_ERR_OUT_OF_MEM:
			LM_NOTICE("out of memory \n");
			break;
		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
		case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
			LM_NOTICE("Self signed certificate "
					"issue\n");
			break;
		case X509_V_ERR_CERT_CHAIN_TOO_LONG:
			LM_NOTICE("certificate chain too long\n");
			break;
		case X509_V_ERR_INVALID_CA:
			LM_NOTICE("invalid CA\n");
			break;
		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
			LM_NOTICE("path length exceeded\n");
			break;
		case X509_V_ERR_INVALID_PURPOSE:
			LM_NOTICE("invalid purpose\n");
			break;
		case X509_V_ERR_CERT_UNTRUSTED:
			LM_NOTICE("certificate untrusted\n");
			break;
		case X509_V_ERR_CERT_REJECTED:
			LM_NOTICE("certificate rejected\n");
			break;

		default:
			LM_NOTICE("something wrong with the cert"
					" ... error code is %d (check x509_vfy.h)\n", ctx->error);
			break;
	}

	LM_NOTICE("verify return:%d\n", pre_verify_ok);
	return(pre_verify_ok);
}
Ejemplo n.º 17
0
/**
 * internal implementation
 */
int worker_rpc_impl(ei_cnode *ec, int s,int wpid)
{
	str module = STR_NULL;
	str function = STR_NULL;
	ei_x_buff args;
	ei_x_buff reply;
	struct msghdr msgh;
	struct iovec cnt[6];
	int rc;

	memset((void*)&args,0,sizeof(args));
	memset((void*)&reply,0,sizeof(reply));
	memset((void*)&msgh,0,sizeof(msgh));

	/* module name length */
	cnt[0].iov_base = &module.len;
	cnt[0].iov_len  = sizeof(int);

	/* function name length */
	cnt[1].iov_base = &function.len;
	cnt[1].iov_len  = sizeof(int);

	/* Erlang args size */
	cnt[2].iov_base = &args.buffsz;
	cnt[2].iov_len  = sizeof(int);

	/* get data size */
	msgh.msg_iov    = cnt;
	msgh.msg_iovlen = 3;
	while ((rc = recvmsg(s, &msgh, MSG_PEEK)) == -1 && errno == EAGAIN)
		;

	if (rc == -1){
		LM_ERR("recvmsg failed (socket=%d): %s\n",s,strerror(errno));
		goto err;
	}

	/* allocate space */
	module.s = (char*)pkg_malloc(module.len+1);
	if (!module.s) {
		LM_ERR("not enough memory\n");
		goto err;
	}

	function.s = (char*)pkg_malloc(function.len+1);
	if (!function.s) {
		LM_ERR("not enough memory\n");
		goto err;
	}

	args.buff = (char*)malloc(args.buffsz);
	if (!args.buff) {
		LM_ERR("malloc: not enough memory\n");
		goto err;
	}

	/* buffers */
	cnt[3].iov_base = module.s;
	cnt[3].iov_len  = module.len;

	cnt[4].iov_base = function.s;
	cnt[4].iov_len  = function.len;

	cnt[5].iov_base = args.buff;
	cnt[5].iov_len  = args.buffsz;

	/* get whole data */
	msgh.msg_iovlen = 6;
	while ((rc = recvmsg(s, &msgh, MSG_WAITALL)) == -1 && errno == EAGAIN)
		;

	if (rc == -1){
		LM_ERR("recvmsg failed (socket=%d): %s\n",s,strerror(errno));
		goto err;
	}

	/* fix str */
	module.s[module.len] = 0;
	function.s[function.len] = 0;

	LM_DBG("rpc: %.*s:%.*s(args)\n",STR_FMT(&module),STR_FMT(&function));

	EI_X_BUFF_PRINT(&args);

	if(!enode) {
		LM_NOTICE("there is no connected Erlang node\n");
		/* reply up with error */
		ei_x_format(&reply, "{error,cnode,~a}", "no_erlang_node");
		goto reply;
	}

	/* do RPC */
	if ((rc = ei_rpc(ec,enode->sockfd,module.s,function.s,args.buff,args.buffsz,&reply)) == ERL_ERROR)
	{
		reply.index = 0; /* re-use reply buffer */

		if (erl_errno)
		{
			ei_x_format(&reply, "{error,cnode,~s}", strerror(erl_errno));
			LM_ERR("ei_rpc failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(erl_errno));
		}
		else if (errno)
		{
			ei_x_format(&reply, "{error,cnode,~s}", strerror(errno));
			LM_ERR("ei_rpc failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(errno));
		}
		else
		{
			ei_x_format(&reply, "{error,cnode,~s}", "Unknown error.");
			LM_ERR("ei_rpc failed on node=<%s> socket=<%d>, Unknown error.\n",ec->thisalivename,enode->sockfd);
		}
	}

reply:
	EI_X_BUFF_PRINT(&reply);

	cnt[0].iov_base = (void*)&wpid;
	cnt[0].iov_len  = sizeof(int);

	/* send reply to Kamailio worker */
	cnt[1].iov_base = (void*)&reply.buffsz;
	cnt[1].iov_len  = sizeof(int);

	cnt[2].iov_base = (void*)reply.buff;
	cnt[2].iov_len  = reply.buffsz;

	msgh.msg_iovlen = 3;
	while ((rc = sendmsg(s, &msgh, 0)) == -1 && errno == EAGAIN)
		;

	if (rc == -1) {
		LM_ERR("sendmsg failed on socket=%d rpid_no=%d; %s\n",s, wpid, strerror(errno));
		goto err;
	};

	pkg_free(module.s);
	pkg_free(function.s);
	free(args.buff);
	ei_x_free(&reply);
	return 0;

err:
	pkg_free(module.s);
	pkg_free(function.s);
	free(args.buff);
	ei_x_free(&reply);
	abort(); /* cant't recover */
	return -1;
}
Ejemplo n.º 18
0
/*
 * Setup default SSL_CTX (and SSL * ) behavior:
 *     verification, cipherlist, acceptable versions, ...
 */
static int init_ssl_ctx_behavior( struct tls_domain *d ) {
	int verify_mode;

#if (OPENSSL_VERSION_NUMBER > 0x10001000L)
	/*
	 * set dh params
	 */
	if (!d->tmp_dh_file) {
		LM_DBG("no DH params file for tls[%s:%d] defined, "
				"using default '%s'\n", ip_addr2a(&d->addr), d->port,
				tls_tmp_dh_file);
		d->tmp_dh_file = tls_tmp_dh_file;
	}
	if (d->tmp_dh_file && set_dh_params(d->ctx, d->tmp_dh_file) < 0)
		return -1;

	if (d->tls_ec_curve) {
		if (set_ec_params(d->ctx, d->tls_ec_curve) < 0) {
			return -1;
		}
	}
	else {
		LM_NOTICE("No EC curve defined\n");
	}
#else
	if (d->tmp_dh_file  || tls_tmp_dh_file)
		LM_WARN("DH params file discarded as not supported by your openSSL version\n");
	if (d->tls_ec_curve)
		LM_WARN("EC params file discarded as not supported by your openSSL version\n");
#endif

	if( d->ciphers_list != 0 ) {
		if( SSL_CTX_set_cipher_list(d->ctx, d->ciphers_list) == 0 ) {
			LM_ERR("failure to set SSL context "
					"cipher list '%s'\n", d->ciphers_list);
			return -1;
		} else {
			LM_NOTICE("cipher list set to %s\n", d->ciphers_list);
		}
	} else {
		LM_DBG( "cipher list null ... setting default\n");
	}

	/* Set a bunch of options:
	 *     do not accept SSLv2 / SSLv3
	 *     no session resumption
	 *     choose cipher according to server's preference's*/

	SSL_CTX_set_options(d->ctx,
			SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
			SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
			SSL_OP_CIPHER_SERVER_PREFERENCE);

	/* Set verification procedure
	 * The verification can be made null with SSL_VERIFY_NONE, or
	 * at least easier with SSL_VERIFY_CLIENT_ONCE instead of
	 * SSL_VERIFY_FAIL_IF_NO_PEER_CERT.
	 * For extra control, instead of 0, we can specify a callback function:
	 *           int (*verify_callback)(int, X509_STORE_CTX *)
	 * Also, depth 2 may be not enough in some scenarios ... though no need
	 * to increase it much further */

	if (d->type & TLS_DOMAIN_SRV) {
		/* Server mode:
		 * SSL_VERIFY_NONE
		 *   the server will not send a client certificate request to the
		 *   client, so the client  will not send a certificate.
		 * SSL_VERIFY_PEER
		 *   the server sends a client certificate request to the client.
		 *   The certificate returned (if any) is checked. If the verification
		 *   process fails, the TLS/SSL handshake is immediately terminated
		 *   with an alert message containing the reason for the verification
		 *   failure. The behaviour can be controlled by the additional
		 *   SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.
		 * SSL_VERIFY_FAIL_IF_NO_PEER_CERT
		 *   if the client did not return a certificate, the TLS/SSL handshake
		 *   is immediately terminated with a ``handshake failure'' alert.
		 *   This flag must be used together with SSL_VERIFY_PEER.
		 * SSL_VERIFY_CLIENT_ONCE
		 *   only request a client certificate on the initial TLS/SSL
		 *   handshake. Do not ask for a client certificate again in case of
		 *   a renegotiation. This flag must be used together with
		 *   SSL_VERIFY_PEER.
		 */

		if( d->verify_cert ) {
			verify_mode = SSL_VERIFY_PEER;
			if( d->require_client_cert ) {
				LM_WARN("client verification activated. Client "
						"certificates are mandatory.\n");
				verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
			} else
				LM_WARN("client verification activated. Client "
						"certificates are NOT mandatory.\n");
		} else {
			verify_mode = SSL_VERIFY_NONE;
			LM_WARN("client verification NOT activated. Weaker security.\n");
		}
	} else {
		/* Client mode:
		 * SSL_VERIFY_NONE
		 *   if not using an anonymous cipher (by default disabled), the
		 *   server will send a certificate which will be checked. The result
		 *   of the certificate verification process can be checked after the
		 *   TLS/SSL handshake using the SSL_get_verify_result(3) function.
		 *   The handshake will be continued regardless of the verification
		 *   result.
		 * SSL_VERIFY_PEER
		 *   the server certificate is verified. If the verification process
		 *   fails, the TLS/SSL handshake is immediately terminated with an
		 *   alert message containing the reason for the verification failure.
		 *   If no server certificate is sent, because an anonymous cipher is
		 *   used, SSL_VERIFY_PEER is ignored.
		 * SSL_VERIFY_FAIL_IF_NO_PEER_CERT
		 *   ignored
		 * SSL_VERIFY_CLIENT_ONCE
		 *   ignored
		 */

		if( d->verify_cert ) {
			verify_mode = SSL_VERIFY_PEER;
			LM_WARN("server verification activated.\n");
		} else {
			verify_mode = SSL_VERIFY_NONE;
			LM_WARN("server verification NOT activated. Weaker security.\n");
		}
	}

	SSL_CTX_set_verify( d->ctx, verify_mode, verify_callback);
	SSL_CTX_set_verify_depth( d->ctx, VERIFY_DEPTH_S);

	SSL_CTX_set_session_cache_mode( d->ctx, SSL_SESS_CACHE_SERVER );
	SSL_CTX_set_session_id_context( d->ctx, OS_SSL_SESS_ID,
			OS_SSL_SESS_ID_LEN );

	return 0;
}
Ejemplo n.º 19
0
int worker_send_impl(ei_cnode *ec, int s,int wpid)
{
	erlang_pid pid;
	ei_x_buff emsg;
	struct msghdr msgh;
	struct iovec cnt[6];
	int rc;

	memset((void*)&emsg,0,sizeof(emsg));

	memset((void*)&msgh,0,sizeof(msgh));

	/* Erlang args size */
	cnt[0].iov_base = &emsg.buffsz;
	cnt[0].iov_len  = sizeof(int);

	/* get data size */
	msgh.msg_iov    = cnt;
	msgh.msg_iovlen = 1;

	while ((rc = recvmsg(s, &msgh, MSG_PEEK)) == -1 && errno == EAGAIN)
		;

	if (rc == -1){
		LM_ERR("recvmsg failed (socket=%d): %s\n",s,strerror(errno));
		return -1;
	}

	emsg.buff = (char*)malloc(emsg.buffsz);
	if (!emsg.buff) {
		LM_ERR("malloc: not enough memory\n");
		goto err;
	}

	/* buffers */
	cnt[1].iov_base = &pid;
	cnt[1].iov_len  = sizeof(erlang_pid);

	cnt[2].iov_base = emsg.buff;
	cnt[2].iov_len  = emsg.buffsz;

	/* get whole data */
	msgh.msg_iovlen = 3;
	while ((rc = recvmsg(s, &msgh, MSG_WAITALL)) == -1 && errno == EAGAIN)
		;

	if (rc == -1){
		LM_ERR("recvmsg failed (socket=%d): %s\n",s,strerror(errno));
		goto err;
	}

	if(!enode) {
		LM_NOTICE("there is no connected Erlang node\n");
		goto err;
	}

	LM_DBG(">> <%s.%d.%d> ! emsg\n",pid.node,pid.num,pid.serial);

	EI_X_BUFF_PRINT(&emsg);

	/* do ERL_SEND */
	if ((rc = ei_send(enode->sockfd,&pid,emsg.buff,emsg.buffsz)) == ERL_ERROR)
	{
		if (erl_errno)
		{
			LM_ERR("ei_send failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(erl_errno));
		}
		else if (errno)
		{
			LM_ERR("ei_send failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(errno));
		}
		else
		{
			LM_ERR("ei_send failed on node=<%s> socket=<%d>, Unknown error.\n",ec->thisalivename,enode->sockfd);
		}
	}

	free(emsg.buff);

	return 0;

err:

	free(emsg.buff);

	return -1;
}
Ejemplo n.º 20
0
/*
 * initialize tls virtual domains
 */
static int init_tls_domains(struct tls_domain *d)
{
	struct tls_domain *dom;

	dom = d;
	while (d) {
		if (d->name.len) {
			LM_INFO("Processing TLS domain '%.*s'\n",
					d->name.len, ZSW(d->name.s));
		} else {
			LM_INFO("Processing TLS domain [%s:%d]\n",
					ip_addr2a(&d->addr), d->port);
		}

		/*
		 * set method
		 */
		if (d->method == TLS_METHOD_UNSPEC) {
			LM_DBG("no method for tls[%s:%d], using default\n",
					ip_addr2a(&d->addr), d->port);
			d->method = tls_default_method;
		}

		/*
		 * create context
		 */
		d->ctx = SSL_CTX_new(ssl_methods[d->method - 1]);
		if (d->ctx == NULL) {
			LM_ERR("cannot create ssl context for "
					"tls[%s:%d]\n", ip_addr2a(&d->addr), d->port);
			return -1;
		}
		if (init_ssl_ctx_behavior( d ) < 0)
			return -1;
		
		/*
		 * load certificate
		 */
		if (!d->cert_file) {
			LM_NOTICE("no certificate for tls[%s:%d] defined, using default"
					"'%s'\n", ip_addr2a(&d->addr), d->port,	tls_cert_file);
			d->cert_file = tls_cert_file;
		}

		if (load_certificate(d->ctx, d->cert_file) < 0)
			return -1;

		/**
		 * load crl from directory
		 */
		if (!d->crl_directory) {
			LM_NOTICE("no crl for tls, using none");
		} else {
			if(load_crl(d->ctx, d->crl_directory, d->crl_check_all) < 0)
				return -1;
		}

		/*
		 * load ca
		 */
		if (!d->ca_file) {
			LM_NOTICE("no CA for tls[%s:%d] defined, "
					"using default '%s'\n", ip_addr2a(&d->addr), d->port,
					tls_ca_file);
			d->ca_file = tls_ca_file;
		}
		if (d->ca_file && load_ca(d->ctx, d->ca_file) < 0)
			return -1;

		/*
		 * load ca from directory
		 */
		if (!d->ca_directory) {

			LM_NOTICE("no CA for tls[%s:%d] defined, "
					"using default '%s'\n", ip_addr2a(&d->addr), d->port,
					tls_ca_dir);
			d->ca_directory = tls_ca_dir;
		}

		if (d->ca_directory && load_ca_dir(d->ctx, d->ca_directory) < 0)
			return -1;

		d = d->next;
	}

	/*
	 * load all private keys as the last step (may prompt for password)
	 */
	d = dom;
	while (d) {
		if (!d->pkey_file) {
			LM_NOTICE("no private key for tls[%s:%d] defined, using default"
					"'%s'\n", ip_addr2a(&d->addr), d->port, tls_pkey_file);
			d->pkey_file = tls_pkey_file;
		}
		if (load_private_key(d->ctx, d->pkey_file) < 0)
			return -1;
		d = d->next;
	}

	return 0;
}
Ejemplo n.º 21
0
int mt_add_to_tree(m_tree_t *pt, str *sp, str *svalue)
{
	int l, ivalue = 0;
	mt_node_t *itn, *itn0;
	mt_is_t *tvalues;

	if(pt==NULL || sp==NULL || sp->s==NULL
			|| svalue==NULL || svalue->s==NULL)
	{
		LM_ERR("bad parameters\n");
		return -1;
	}

	if(sp->len>=MT_MAX_DEPTH)
	{
		LM_ERR("max prefix len exceeded\n");
		return -1;
	}

	if ((pt->type == MT_TREE_IVAL) && (str2sint(svalue, &ivalue) != 0)) {
		LM_ERR("bad integer string <%.*s>\n", svalue->len, svalue->s);
		return -1;
	}

	l = 0;
	if(pt->head == NULL)
	{
		pt->head = (mt_node_t*)shm_malloc(MT_NODE_SIZE*sizeof(mt_node_t));
		if(pt->head == NULL)
		{
			LM_ERR("no more shm memory for tree head\n");
			return -1;
		}
		memset(pt->head, 0, MT_NODE_SIZE*sizeof(mt_node_t));
		pt->nrnodes++;
		pt->memsize +=  MT_NODE_SIZE*sizeof(mt_node_t);
	}

	itn0 = pt->head;
	if(_mt_char_table[(unsigned int)sp->s[l]]==255)
	{
		LM_ERR("invalid char %d in prefix [%c (0x%x)]\n",
				l, sp->s[l], sp->s[l]);
		return -1;			
	}
	itn = itn0[_mt_char_table[(unsigned int)sp->s[l]]].child;

	while(l < sp->len-1)
	{
		if(itn == NULL)
		{
			itn = (mt_node_t*)shm_malloc(MT_NODE_SIZE*sizeof(mt_node_t));
			if(itn == NULL)
			{
				LM_ERR("no more shm mem\n");
				return -1;
			}
			memset(itn, 0, MT_NODE_SIZE*sizeof(mt_node_t));
			pt->nrnodes++;
			pt->memsize +=  MT_NODE_SIZE*sizeof(mt_node_t);
			itn0[_mt_char_table[(unsigned int)sp->s[l]]].child = itn;
		}
		l++;	
		if(_mt_char_table[(unsigned int)sp->s[l]]==255)
		{
			LM_ERR("invalid char %d in prefix [%c (0x%x)]\n",
					l, sp->s[l], sp->s[l]);
			return -1;			
		}
		itn0 = itn;
		itn = itn0[_mt_char_table[(unsigned int)sp->s[l]]].child;
	}

	if(itn0[_mt_char_table[(unsigned int)sp->s[l]]].tvalues != NULL) {
		if(_mt_ignore_duplicates != 0) {
			LM_NOTICE("prefix already allocated [%.*s/%.*s]\n",
					sp->len, sp->s, svalue->len, svalue->s);
			return 1;
		} else if (_mt_allow_duplicates == 0) {
			LM_ERR("prefix already allocated [%.*s/%.*s]\n",
					sp->len, sp->s, svalue->len, svalue->s);
			return -1;
		}
	}

	tvalues = (mt_is_t *)shm_malloc(sizeof(mt_is_t));
	if (tvalues == NULL) {
		LM_ERR("no more shm mem for tvalue\n");
		return -1;
	}
	memset(tvalues, 0, sizeof(mt_is_t));

	if (pt->type == MT_TREE_IVAL) {
		tvalues->tvalue.n = ivalue;
	} else { /* pt->type == MT_TREE_SVAL or MT_TREE_DW */
		tvalues->tvalue.s.s = (char*)shm_malloc((svalue->len+1)*sizeof(char));
		if (tvalues->tvalue.s.s == NULL) {
			LM_ERR("no more shm mem for string\n");
			return -1;
		}
		tvalues->tvalue.s.len = svalue->len;
		pt->memsize +=  (svalue->len+1)*sizeof(char);
		pt->nritems++;
		strncpy(tvalues->tvalue.s.s, svalue->s, svalue->len);
		tvalues->tvalue.s.s[svalue->len] = '\0';
	}
	tvalues->next = itn0[_mt_char_table[(unsigned int)sp->s[l]]].tvalues;
	itn0[_mt_char_table[(unsigned int)sp->s[l]]].tvalues = tvalues;

	mt_node_set_payload(&itn0[_mt_char_table[(unsigned int)sp->s[l]]],
			pt->type);
	return 0;
}
Ejemplo n.º 22
0
/*
 * Send an SQL query to the server
 */
static int db_oracle_submit_query(const db_con_t* _h, const str* _s)
{
	OCIBind* bind[MAX_BIND_HANDLES];
	OCIDate odt[sizeof(bind)/sizeof(bind[0])];
	str tmps;
	sword status;
	int pass;
	ora_con_t* con = CON_ORA(_h);
	query_data_t* pqd = con->pqdata;
	size_t hc = pqd->_n + pqd->_nw;
	OCIStmt *stmthp;

	if (hc >= sizeof(bind)/sizeof(bind[0])) {
		LM_ERR("too many bound. Rebuild with MAX_BIND_HANDLES >= %u\n",
			(unsigned)hc);
		return -1;
	}
	
	if (!pqd->_rs) {
		/*
		 * This method is at ~25% faster as set OCI_COMMIT_ON_SUCCESS
		 * in StmtExecute
		 */
		tmps.len = snprintf(st_buf, sizeof(st_buf),
			"begin %.*s; commit write batch nowait; end;",
			_s->len, _s->s);
		if ((unsigned)tmps.len >= sizeof(st_buf))
			return sql_buf_small();
		tmps.s = st_buf;
		_s = &tmps;
	}

	pass = 1;
	if (!con->connected) {
		status = db_oracle_reconnect(con);
		if (status != OCI_SUCCESS) {
			LM_ERR("can't restore connection: %s\n", db_oracle_error(con, status));
			return -2;
		}
		LM_INFO("connection restored\n");
		--pass;
	}
repeat:
	stmthp = NULL;
	status = OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&stmthp,
		    OCI_HTYPE_STMT, 0, NULL);
	if (status != OCI_SUCCESS)
		goto ora_err;
	status = OCIStmtPrepare(stmthp, con->errhp, (text*)_s->s, _s->len,
		OCI_NTV_SYNTAX, OCI_DEFAULT);
	if (status != OCI_SUCCESS)
		goto ora_err;

	if (hc) {
		bmap_t bmap;
		size_t pos = 1;
		int i;

		memset(bind, 0, hc*sizeof(bind[0]));
		for (i = 0; i < pqd->_n; i++) {
			if (db_oracle_val2bind(&bmap, &pqd->_v[i], &odt[pos]) < 0)
				goto bind_err;
			status = OCIBindByPos(stmthp, &bind[pos], con->errhp,
				pos, bmap.addr, bmap.size, bmap.type,
				NULL, NULL, NULL, 0, NULL, OCI_DEFAULT);
			if (status != OCI_SUCCESS)
				goto ora_err;
			++pos;
		}
		for (i = 0; i < pqd->_nw; i++) {
			if (db_oracle_val2bind(&bmap, &pqd->_w[i], &odt[pos]) < 0) {
bind_err:
				OCIHandleFree(stmthp, OCI_HTYPE_STMT);
				LM_ERR("can't map values\n");
				return -3;
			}
			status = OCIBindByPos(stmthp, &bind[pos], con->errhp,
				pos, bmap.addr, bmap.size, bmap.type,
				NULL, NULL, NULL, 0, NULL, OCI_DEFAULT);
			if (status != OCI_SUCCESS)
				goto ora_err;
			++pos;
		}
	}

	// timelimited operation
	status = begin_timelimit(con, 0);
	if (status != OCI_SUCCESS) goto ora_err;
	do status = OCIStmtExecute(con->svchp, stmthp, con->errhp,
		!pqd->_rs, 0, NULL, NULL,
		pqd->_rs ? OCI_STMT_SCROLLABLE_READONLY : OCI_DEFAULT);
	while (wait_timelimit(con, status));
	if (done_timelimit(con, status)) goto stop_exec;
	switch (status)	{
	case OCI_SUCCESS_WITH_INFO:
		LM_WARN("driver: %s\n", db_oracle_errorinfo(con));
		//PASS THRU
	case OCI_SUCCESS:
		if (pqd->_rs)
			*pqd->_rs = stmthp;
		else
			OCIHandleFree(stmthp, OCI_HTYPE_STMT);
		return 0;
	default:
	    pass = -pass;
	    break;
	}

ora_err:
	LM_ERR("driver: %s\n", db_oracle_error(con, status));
stop_exec:
	if (stmthp)
		OCIHandleFree(stmthp, OCI_HTYPE_STMT);
	if (pass == -1 && !con->connected) {
		/* Attemtp to reconnect */
		if (db_oracle_reconnect(con) == OCI_SUCCESS) {
			LM_NOTICE("attempt repeat after reconnect\n");
			pass = 0;
			goto repeat;
		}
		LM_ERR("connection loss\n");
	}
	return -4;
}
Ejemplo n.º 23
0
/* UPDATED + CHECKED
 */
static inline char *run_log( struct cpl_interpreter *intr )
{
	char  *p;
	unsigned short attr_name;
	unsigned short n;
	str name    = {0,0};
	str comment = {0,0};
	str user;
	int i;

	/* sanity check */
	if (NR_OF_KIDS(intr->ip)>1) {
		LM_ERR("LOG node suppose to have max one child"
			", not %d!\n",NR_OF_KIDS(intr->ip));
		goto script_error;
	}

	/* is logging enabled? */
	if ( cpl_env.log_dir==0 )
		goto done;

	/* read the attributes of the LOG node*/
	p = ATTR_PTR(intr->ip);
	for( i=NR_OF_ATTR(intr->ip); i>0 ; i-- ) {
		get_basic_attr( p, attr_name, n, intr, script_error);
		switch (attr_name) {
			case NAME_ATTR:
				get_str_attr( p, name.s, n, intr, script_error,1);
				name.len = n;
				break;
			case COMMENT_ATTR:
				get_str_attr( p, comment.s, n, intr, script_error,1);
				comment.len = n;
				break;
			default:
				LM_ERR("unknown attribute "
					"(%d) in LOG node\n",attr_name);
				goto script_error;
		}
	}

	if (comment.len==0) {
		LM_NOTICE("LOG node has no comment attr -> skipping\n");
		goto done;
	}

	user.len = intr->user.len + name.len + comment.len;
	/* duplicate the attrs in shm memory */
	user.s = p = (char*)shm_malloc( user.len );
	if (!user.s) {
		LM_ERR("no more shm memory!\n");
		goto runtime_error;
	}
	/* copy the user name */
	memcpy( p, intr->user.s, intr->user.len);
	user.len = intr->user.len;
	p += intr->user.len;
	/* copy the log name */
	if (name.len) {
		memcpy( p, name.s, name.len );
		name.s = p;
		p += name.len;
	}
	/* copy the comment */
	memcpy( p, comment.s, comment.len);
	comment.s = p;

	/* send the command */
	write_cpl_cmd( CPL_LOG_CMD, &user, &name, &comment );

done:
	return get_first_child(intr->ip);
runtime_error:
	return CPL_RUNTIME_ERROR;
script_error:
	return CPL_SCRIPT_ERROR;
}
Ejemplo n.º 24
0
/*
 * destroy function
 */
static void destroy(void)
{
    LM_NOTICE("destroy module ...\n");
    /* closing sockets */
    rmq_destroy_pipe();
}
Ejemplo n.º 25
0
int k_sd_journal_send_xavp(str *rname)
{
	struct _sr_xavp *rxavp, *nxavp;
	int cnt, buflen, i, ret;
	struct iovec *logv;

	rxavp = xavp_get(rname, NULL);

	if (!rxavp || rxavp->val.type != SR_XTYPE_XAVP) {
		LM_ERR("not a valid xavp: %.*s?\n", rname->len, rname->s);
	}

	/* first, count xavp nodes */
	for (nxavp = rxavp->val.v.xavp, cnt = 0;
			nxavp;
			nxavp = nxavp->next, cnt++);

	if (cnt == 0) {
		/* nothing to log? */
		LM_NOTICE("empty xavp: %.*s?, no log event was sent to journald\n",
				rname->len,
				rname->s);
		return 1;
	}

	logv = pkg_malloc(cnt * sizeof (struct iovec));

	if (!logv) {
		LM_ERR("failed to allocate pkg memory\n");
		return -1;
	}

	ret = -1;

	for (nxavp = rxavp->val.v.xavp, cnt = 0;
			nxavp;
			nxavp = nxavp->next, cnt++)
	{
		if (nxavp->val.type == SR_XTYPE_INT) {
			buflen = snprintf(NULL, 0,
					"%.*s=%d",
					nxavp->name.len, nxavp->name.s,
					nxavp->val.v.i);
			logv[cnt].iov_base = pkg_malloc(buflen + 1/*snprintf's trailing \0*/);
			if (!logv[cnt].iov_base ) {
				LM_ERR("failed to allocate pkg memory\n");
				goto free;
			}
			logv[cnt].iov_len = buflen;

			snprintf(logv[cnt].iov_base, buflen + 1,
					"%.*s=%d",
					nxavp->name.len, nxavp->name.s,
					nxavp->val.v.i);
		} else if (nxavp->val.type == SR_XTYPE_STR) {
			buflen = nxavp->name.len + 1 + nxavp->val.v.s.len;
			logv[cnt].iov_base = pkg_malloc(buflen);
			if (!logv[cnt].iov_base) {
				LM_ERR("failed to allocate pkg memory\n");
				goto free;
			}
			logv[cnt].iov_len = buflen;

			memcpy(logv[cnt].iov_base, nxavp->name.s, nxavp->name.len);
			((char*)logv[cnt].iov_base)[nxavp->name.len] = '=';
			memcpy(((char*)(logv[cnt].iov_base)) + nxavp->name.len + 1,
					nxavp->val.v.s.s,
					nxavp->val.v.s.len);
		} else {
			LM_NOTICE("unsupported type %d for field %.*s, skipped...\n",
					nxavp->val.type,
					nxavp->name.len, nxavp->name.s);
			logv[cnt].iov_len = 0;
			logv[cnt].iov_base = NULL;
		}
		LM_DBG("added io slice %d: %.*s\n", cnt, (int)logv[cnt].iov_len, (char*)logv[cnt].iov_base);
	}

	if (sd_journal_sendv(logv, cnt) != 0) {
		LM_ERR("sd_journal_sendv() failed\n");
	} else {
		ret = 1;
	}

free:
	for (i = 0 ; i < cnt ; i++) {
		if (logv[i].iov_base) pkg_free(logv[i].iov_base);
	}
	pkg_free(logv);
	return ret;
}
Ejemplo n.º 26
0
Archivo: cpl.c Proyecto: NormB/opensips
static int cpl_init(void)
{
	bind_usrloc_t bind_usrloc;
	struct stat   stat_t;
	char *ptr;
	int val;

	init_db_url( db_url , 0 /*cannot be null*/);
	db_table.len = strlen(db_table.s);

	LM_INFO("initializing...\n");

	if (proxy_route && proxy_route[0]) {
		cpl_env.proxy_route = get_script_route_ID_by_name( proxy_route,
				rlist, RT_NO);
		if (cpl_env.proxy_route==-1) {
			LM_ERR("route <%s> does not exist\n",proxy_route);
			return -1;
		}
	}

	if (cpl_env.proxy_recurse>MAX_PROXY_RECURSE) {
		LM_CRIT("value of proxy_recurse param (%d) exceeds "
			"the maximum safety value (%d)\n",
			cpl_env.proxy_recurse,MAX_PROXY_RECURSE);
		goto error;
	}

	if (dtd_file==0) {
		LM_CRIT("mandatory parameter \"cpl_dtd_file\" found empty\n");
		goto error;
	} else {
		/* check if the dtd file exists */
		if (stat( dtd_file, &stat_t)==-1) {
			LM_ERR("checking file \"%s\" status failed; stat returned %s\n",
					dtd_file,strerror(errno));
			goto error;
		}
		if ( !S_ISREG( stat_t.st_mode ) ) {
			LM_ERR("dir \"%s\" is not a regular file!\n", dtd_file);
			goto error;
		}
		if (access( dtd_file, R_OK )==-1) {
			LM_ERR("checking file \"%s\" for permissions "
				"failed; access returned %s\n",dtd_file,strerror(errno));
			goto error;
		}
	}

	if (cpl_env.log_dir==0) {
		LM_INFO("log_dir param found empty -> logging disabled!\n");
	} else {
		if ( strlen(cpl_env.log_dir)>MAX_LOG_DIR_SIZE ) {
			LM_ERR("dir \"%s\" has a too long name :-(!\n",	cpl_env.log_dir);
			goto error;
		}
		/* check if the dir exists */
		if (stat( cpl_env.log_dir, &stat_t)==-1) {
			LM_ERR("checking dir \"%s\" status failed;"
				" stat returned %s\n",cpl_env.log_dir,strerror(errno));
			goto error;
		}
		if ( !S_ISDIR( stat_t.st_mode ) ) {
			LM_ERR("dir \"%s\" is not a directory!\n", cpl_env.log_dir);
			goto error;
		}
		if (access( cpl_env.log_dir, R_OK|W_OK )==-1) {
			LM_ERR("checking dir \"%s\" for permissions failed; access "
					"returned %s\n", cpl_env.log_dir, strerror(errno));
			goto error;
		}
	}

	/* bind to the mysql module */
	if (cpl_db_bind(&db_url, &db_table)<0) goto error;

	/* load TM API */
	if (load_tm_api(&cpl_fct.tmb)!=0) {
		LM_ERR("can't load TM API\n");
		goto error;
	}
	/* load SIGNALING API */
	if(load_sig_api(&cpl_fct.sigb)< 0) {
		LM_ERR("can't load signaling functions\n");
		return -1;
	}


	/* bind to usrloc module if requested */
	if (lookup_domain) {
		/* import all usrloc functions */
		bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
		if (!bind_usrloc) {
			LM_ERR("can't bind usrloc\n");
			goto error;
		}
		if (bind_usrloc( &(cpl_fct.ulb) ) < 0) {
			LM_ERR("importing usrloc failed\n");
			goto error;
		}
		/* convert lookup_domain from char* to udomain_t* pointer */
		if (cpl_fct.ulb.register_udomain( lookup_domain, &cpl_env.lu_domain)
		< 0) {
			LM_ERR("failed to register domain <%s>\n",lookup_domain);
			goto error;
		}
	} else {
		LM_NOTICE("no lookup_domain given -> disable lookup node\n");
	}

	/* build a pipe for sending commands to aux process */
	if ( pipe( cpl_env.cmd_pipe )==-1 ) {
		LM_CRIT("cannot create command pipe: %s!\n", strerror(errno) );
		goto error;
	}
	/* set the writing non blocking */
	if ( (val=fcntl(cpl_env.cmd_pipe[1], F_GETFL, 0))<0 ) {
		LM_ERR("getting flags from pipe[1] failed: fcntl said %s!\n",
				strerror(errno));
		goto error;
	}
	if ( fcntl(cpl_env.cmd_pipe[1], F_SETFL, val|O_NONBLOCK) ) {
		LM_ERR("setting flags to pipe[1] failed: fcntl said %s!\n",
				strerror(errno));
		goto error;
	}

	/* init the CPL parser */
	if (init_CPL_parser( dtd_file )!=1 ) {
		LM_ERR("init_CPL_parser failed!\n");
		goto error;
	}

	/* make a copy of the original TZ env. variable */
	ptr = getenv("TZ");
	cpl_env.orig_tz.len = 3/*"TZ="*/ + (ptr?(strlen(ptr)+1):0);
	if ( (cpl_env.orig_tz.s=shm_malloc( cpl_env.orig_tz.len ))==0 ) {
		LM_ERR("no more shm mem. for saving TZ!\n");
		goto error;
	}
	memcpy(cpl_env.orig_tz.s,"TZ=",3);
	if (ptr)
		strcpy(cpl_env.orig_tz.s+3,ptr);

	/* convert realm_prefix from string null terminated to str */
	if (cpl_env.realm_prefix.s) {
		cpl_env.realm_prefix.len = strlen(cpl_env.realm_prefix.s);
		/* convert the realm_prefix to lower cases */
		strlower( &cpl_env.realm_prefix );
	}

	return 0;
error:
	return -1;
}
Ejemplo n.º 27
0
/*! \brief send a message over an already opened TCP connection */
int tcp_send_recv(int sockfd, char* buf, int len, rd_buf_t* rb, 
					unsigned int waited_id)
{
	int n, number_of_tries;
	fd_set active_fd_set, read_fd_set;
	struct timeval tv;
	unsigned long int result_code;
	AAAMessage *msg;
	AAA_AVP	*avp;
	char serviceType;
	unsigned int m_id;

	/* try to write the message to the Diameter client */
	while( (n=write(sockfd, buf, len))==-1 ) 
	{
		if (errno==EINTR)
			continue;
		LM_ERR("write returned error: %s\n", strerror(errno));
		return AAA_ERROR;
	}

	if (n!=len) 
	{
		LM_ERR("write gave no error but wrote less than asked\n");
		return AAA_ERROR;
	}
	/* wait for the answer a limited amount of time */
	tv.tv_sec = MAX_WAIT_SEC;
	tv.tv_usec = MAX_WAIT_USEC;

	/* Initialize the set of active sockets. */
	FD_ZERO (&active_fd_set);
	FD_SET (sockfd, &active_fd_set);
	number_of_tries = 0;

	while(number_of_tries<MAX_TRIES)
	{
		read_fd_set = active_fd_set;
		if (select (sockfd+1, &read_fd_set, NULL, NULL, &tv) < 0)
		{
			LM_ERR("select function failed\n");
			return AAA_ERROR;
		}

/*		if (!FD_ISSET (sockfd, &read_fd_set))
		{
			LM_ERR("no response received\n");
//			return AAA_ERROR;
		}
*/		/* Data arriving on a already-connected socket. */
		reset_read_buffer(rb);
		switch( do_read(sockfd, rb) )
		{
			case CONN_ERROR:
				LM_ERR("failed to read from socket\n");
				return AAA_CONN_CLOSED;
			case CONN_CLOSED:
				LM_ERR("failed to read from socket\n");
				return AAA_CONN_CLOSED;
		}
		
		/* obtain the structure corresponding to the message */
		msg = AAATranslateMessage(rb->buf, rb->buf_len, 0);	
		if(!msg)
		{
			LM_ERR("message structure not obtained\n");	
			return AAA_ERROR;
		}
		avp = AAAFindMatchingAVP(msg, NULL, AVP_SIP_MSGID,
								vendorID, AAA_FORWARD_SEARCH);
		if(!avp)
		{
			LM_ERR("AVP_SIP_MSGID not found\n");
			return AAA_ERROR;
		}
		m_id = *((unsigned int*)(avp->data.s));
		LM_DBG("######## m_id=%d\n", m_id);
		if(m_id!=waited_id)
		{
			number_of_tries ++;
			LM_NOTICE("old message received\n");
			continue;
		}
		goto next;
	}

	LM_ERR("too many old messages received\n");
	return AAA_TIMEOUT;
next:

	/* Finally die correct answer */
	avp = AAAFindMatchingAVP(msg, NULL, AVP_Service_Type,
							vendorID, AAA_FORWARD_SEARCH);
	if(!avp)
	{
		LM_ERR("AVP_Service_Type not found\n");
		return AAA_ERROR;
	}
	serviceType = avp->data.s[0];

	result_code = ntohl(*((unsigned long int*)(msg->res_code->data.s)));
	switch(result_code)
	{
		case AAA_SUCCESS:					/* 2001 */
			return ACC_SUCCESS;
		default:							/* error */
			return ACC_FAILURE;
	}
}
Ejemplo n.º 28
0
int _impl_reg_send(const str *server, const ei_x_buff *msg)
{
	struct msghdr msgh;
	struct iovec cnt[6];
	int pid_no = my_pid();
	eapi_t api = API_REG_SEND;
	int buffsz;
	int rc;
	int i=0,version;

	memset(&msgh, 0, sizeof(msgh));
	memset(&cnt, 0, sizeof(cnt));

	if (ei_decode_version(msg->buff,&i,&version)) {
		LM_ERR("msg must be encoded with version\n");
		return -1;
	}

	if (!csockfd) {

		if (!enode) {
			LM_NOTICE("there is no connected Erlang node\n");
			return -1;
		}

		if (rex_call_in_progress) {
			LM_ERR("RPC in progress detected\n");
			return -1;
		}

		/* do ERL_REG_SEND in event route */
		if ((rc = ei_reg_send(&enode->ec,enode->sockfd,server->s,msg->buff,msg->buffsz)) == ERL_ERROR)
		{
			if (erl_errno)
			{
				LM_ERR("ei_reg_send failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(erl_errno));
			}
			else if (errno)
			{
				LM_ERR("ei_reg_send failed on node=<%s> socket=<%d>: %s\n",enode->conn.nodename,enode->sockfd,strerror(errno));
			}
			else
			{
				LM_ERR("ei_reg_send failed on node=<%s> socket=<%d>, Unknown error.\n",enode->ec.thisalivename,enode->sockfd);
			}
		}
		/* reset response */
		enode->response.index = 0;
		return 0;
	}

	/* Kamailio PID */
	cnt[0].iov_base = (void*)&pid_no;
	cnt[0].iov_len  = sizeof(pid_no);

	/* method */
	cnt[1].iov_base = (void*)&api;
	cnt[1].iov_len = sizeof(api);

	/* put size of following data */
	cnt[2].iov_base = (void*)&server->len;
	cnt[2].iov_len  = sizeof(int);

	buffsz = msg->index; /* occupied size */
	cnt[3].iov_base = (void*)&buffsz;
	cnt[3].iov_len = sizeof(buffsz);

	/* module name */
	cnt[4].iov_base = (void*)server->s;
	cnt[4].iov_len  = server->len;

	/* Erlang arguments content */
	cnt[5].iov_base = (void*)msg->buff;
	cnt[5].iov_len = buffsz; /* occupied size */

	msgh.msg_iov = cnt;
	msgh.msg_iovlen = 6;

	while ((rc = sendmsg(csockfd, &msgh, 0)) == -1 && errno == EAGAIN)
		;

	if (rc == -1) {
		LM_ERR("sendmsg failed: %s\n",strerror(errno));
		return -1;
	}

	/* no reply */

	return 0;
}
Ejemplo n.º 29
0
Archivo: acc.c Proyecto: iamroger/voip
int acc_diam_request( struct sip_msg *req, struct sip_msg *rpl)
{
	int attr_cnt;
	int cnt;
	AAAMessage *send = NULL;
	AAA_AVP *avp;
	struct sip_uri puri;
	str *uri;
	int ret;
	int i;
	int status;
	char tmp[2];
	unsigned int mid;

	attr_cnt = core2strar( req, val_arr);
	/* last value is not used */
	attr_cnt--;

	if ( (send=AAAInMessage(ACCOUNTING_REQUEST, AAA_APP_NASREQ))==NULL) {
		LM_ERR("failed to create new AAA request\n");
		return -1;
	}

	/* AVP_ACCOUNTIG_RECORD_TYPE */
	if( (status = diam_status(req, acc_env.code))<0) {
		LM_ERR("status unknown\n");
		goto error;
	}
	tmp[0] = status+'0';
	tmp[1] = 0;
	if( (avp=AAACreateAVP(AVP_Accounting_Record_Type, 0, 0, tmp,
	1, AVP_DUPLICATE_DATA)) == 0) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("avp not added \n");
		AAAFreeAVP(&avp);
		goto error;
	}
	/* SIP_MSGID AVP */
	mid = req->id;
	if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&mid), 
	sizeof(mid), AVP_DUPLICATE_DATA)) == 0) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("avp not added \n");
		AAAFreeAVP(&avp);
		goto error;
	}

	/* SIP Service AVP */
	if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_ACCOUNTING, 
	SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}
	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("avp not added \n");
		AAAFreeAVP(&avp);
		goto error;
	}

	/* also the extra attributes */
	attr_cnt += extra2strar( dia_extra, rpl, req, val_arr, 0);

	/* add attributes */
	for(i=0; i<attr_cnt; i++) {
		if((avp=AAACreateAVP(diam_attrs[i], 0,0, val_arr[i].s, val_arr[i].len,
		AVP_DUPLICATE_DATA)) == 0) {
			LM_ERR("failed to create AVP: no more free memory!\n");
			goto error;
		}
		if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
			LM_ERR("avp not added \n");
			AAAFreeAVP(&avp);
			goto error;
		}
	}

	/* and the leg attributes */
	if ( leg_info ) {
		cnt = legs2strar(leg_info,req,val_arr,1);
		do {
			for (i=0; i<cnt; i++) {
				if((avp=AAACreateAVP(diam_attrs[attr_cnt+i], 0, 0,
				val_arr[i].s, val_arr[i].len, AVP_DUPLICATE_DATA)) == 0) {
					LM_ERR("failed to create AVP: no more free memory!\n");
					goto error;
				}
				if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
					LM_ERR("avp not added \n");
					AAAFreeAVP(&avp);
					goto error;
				}
			}
		} while ( (cnt=legs2strar(leg_info,req,val_arr,0))!=0 );
	}

	if (get_uri(req, &uri) < 0) {
		LM_ERR("failed to get uri, From/To URI not found\n");
		goto error;
	}

	if (parse_uri(uri->s, uri->len, &puri) < 0) {
		LM_ERR("failed to parse From/To URI\n");
		goto error;
	}

	/* Destination-Realm AVP */
	if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s,
	puri.host.len, AVP_DUPLICATE_DATA)) == 0) {
		LM_ERR("failed to create AVP:no more free memory!\n");
		goto error;
	}

	if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
		LM_ERR("avp not added \n");
		AAAFreeAVP(&avp);
		goto error;
	}

	/* prepare the message to be sent over the network */
	if(AAABuildMsgBuffer(send) != AAA_ERR_SUCCESS) {
		LM_ERR("message buffer not created\n");
		goto error;
	}

	if(sockfd==AAA_NO_CONNECTION) {
		sockfd = init_mytcp(diameter_client_host, diameter_client_port);
		if(sockfd==AAA_NO_CONNECTION) {
			LM_ERR("failed to reconnect to Diameter client\n");
			goto error;
		}
	}

	/* send the message to the DIAMETER client */
	ret = tcp_send_recv(sockfd, send->buf.s, send->buf.len, rb, req->id);
	if(ret == AAA_CONN_CLOSED) {
		LM_NOTICE("connection to Diameter client closed.It will be "
				"reopened by the next request\n");
		close(sockfd);
		sockfd = AAA_NO_CONNECTION;
		goto error;
	}

	if(ret != ACC_SUCCESS) {
		/* a transmission error occurred */
		LM_ERR("message sending to the DIAMETER backend authorization "
				"server failed\n");
		goto error;
	}

	AAAFreeMessage(&send);
	return 1;

error:
	AAAFreeMessage(&send);
	return -1;
}
Ejemplo n.º 30
0
static int w_handle_call(struct sip_msg *msg, char *flow_var)
{
	struct cc_flow *flow;
	struct cc_call *call;
	str leg = {NULL,0};
	str *dn;
	str val;
	int dec;
	int ret = -1;

	call = NULL;
	dec = 0;

	/* get the flow name */
	if (fixup_get_svalue(msg, (gparam_p)flow_var, &val)!=0) {
		LM_ERR("failed to avaluate the flow name variable\n");
		return -1;
	}

	/* parse FROM URI */
	if (parse_from_uri(msg)==NULL) {
		LM_ERR("failed to parse from hdr\n");
		return -2;
	}

	lock_get( data->lock );

	/* get the flow ID */
	flow = get_flow_by_name(data, &val);
	if (flow==NULL) {
		LM_ERR("flow <%.*s> does not exists\n", val.len, val.s);
		ret = -3;
		goto error;
	}
	LM_DBG("using call flow %p\n", flow);

	if (flow->logged_agents==0 /* no logged agents */ ) {
		LM_NOTICE("flow <%.*s> closed\n",flow->id.len,flow->id.s);
		ret = -4;
		goto error;
	}

	update_stat(stg_incalls, 1);
	update_stat(flow->st_incalls, 1);

	if (flow->cid.len) {
		dn = build_displayname(&flow->cid, get_from(msg));
	} else if (get_from(msg)->display.len) {
		dn = &get_from(msg)->display;
	} else {
		dn = &get_from(msg)->parsed_uri.user;
	}
	LM_DBG("cid=<%.*s>\n",dn->len,dn->s);

	call = new_cc_call(data, flow, dn, &get_from(msg)->parsed_uri.user);
	if (call==NULL) {
		LM_ERR("failed to create new call\n");
		ret = -5;
		goto error;
	}
	call->fst_flags |= FSTAT_INCALL;

	/* get estimated wait time */
	call->eta = (unsigned int) (( flow->avg_call_duration *
		(float)get_stat_val(flow->st_queued_calls) ) /
		(float)flow->logged_agents);
	
	LM_DBG("avg_call_duration=%.2f queued_calls=%lu logedin_agents=%u\n",
		flow->avg_call_duration, get_stat_val(flow->st_queued_calls),
		flow->logged_agents);

	LM_DBG("ETA for new call(%p) is %d\n", call, call->eta);

	/* one more call to process */
	flow->ongoing_calls++;

	/* there is no need to lock the call here as it is not 
	 * yet sharead at all - just we have a ref to it */
	
	/* get the first state */
	if (cc_call_state_machine( data, call, &leg )!=0) {
		LM_ERR("failed to get first call destination \n");
		ret = -5;
		goto error;
	}

	lock_release( data->lock );
	LM_DBG("new destination for call(%p) is %.*s (state=%d)\n",
		call, leg.len, leg.s, call->state);

	/* call still waits for agent ? */
	if (call->state!=CC_CALL_TOAGENT) {
		LM_DBG("** onhold++ Not to agent [%p]\n", call);
		update_stat( stg_onhold_calls, +1);
		update_stat( flow->st_onhold_calls, +1);
		dec = 1;
	}

	/* send call to selected destination */
	if (set_call_leg( msg, call, &leg)< 0 ) {
		LM_ERR("failed to set new destination for call\n");
		if (dec) { 
			LM_DBG("** onhold-- Error [%p]\n", call);
			update_stat( stg_onhold_calls, -1);
			update_stat( flow->st_onhold_calls, -1);
		}
		pkg_free(leg.s);
		goto error1;
	}

	pkg_free(leg.s);

	if(cc_db_insert_call(call) < 0) {
		LM_ERR("Failed to insert call record in db\n");
	}

	return 1;
error:
	lock_release( data->lock );
error1:
	if (call) { free_cc_call( data, call); flow->ongoing_calls--; }
	return ret;
}