Kamailio+Freeswitch二次环境搭建及验证

2023-05-02 15:35:37 浏览数 (2)

接上篇:https://cloud.tencent.com/developer/article/2277705

一件事情遗忘的速度远远超过你学习新知识的速度,磨刀不误砍柴工!

版本:

kamailio-5.5.4

freeswitch-1.10.0

使用docker容器搭建这个环境,方便多服务的启动和打包验证,虽然之前也做了一次,但上一次做kamailio代理freeswitch验证的时候,使用了给docker配置独立IP的方式,确实网络上简单很多,这次使用的是docker的端口转发,多了几个问题,最简单的是docker udp端口池如何配置,然后docker会内部创建一个172.17.0.1的网关,充当docker容器和外头网络通信的路由功能,所以出现了新的问题;

添加用户kamctl add username1 password1

    kamctl add 1002 1234

    kamctl add 1010 1234

    kamctl add 1009 1234

    kamctl add 1003 1234

显示在线用户:

kamctl ul show

dispatcher.list中配置的FS是internal口,还是external口,测试看两个都可以:

代码语言:javascript复制
# $Id$
# dispatcher destination sets
# setit(int) destination(sip uri) flags(int,opt) priority(int,opt) attributes(str,opt)

# Freeswitch IPS
2 sip:192.168.16.35:5060
4 sip:192.168.16.35:5060

出现的问题

1、主叫CANCEL转不到被叫客户端

2、主、被叫挂断,FS一直给KAMAILIO发送DECLINE

3、主、被叫接听,FS一直给KAMAILIO发送200 OK,由于被叫的ACK没有转发到KAMAILIO,转发失败的原因是kamailio转出来的200OK的报文中,多了一个Record-route的字段,地址是172.17.0.2的内外地址,导致linphone回复ACK失败,FS就不停的发送200OK;

----20220325更新--后来发现record_route还是有帮助的,否则ACK报文不能正常返回,修改为kamailio所在机器的对外IP地址-------------------

 //record_route();

record_route_preset("192.168.16.83:5060");

如下就是修改kamailio.cfg中增加WITH_FREEWITCH的相关脚本:

代码语言:javascript复制
#!ifdef WITH_FREESWITCH
loadmodule "uac.so"
loadmodule "path.so"

freeswitch.bindip = "172.17.0.1" desc "FreeSWITCH IP Address"
freeswitch.bindport = "5260" desc "FreeSWITCH Port"

//reply_to_via=1
#!endif


#!ifdef WITH_FREESWITCH
modparam("rr", "append_fromtag", 1)
#!else
modparam("rr", "append_fromtag", 0)
#!endif
 
 

#!ifdef WITH_FREESWITCH
# Test if coming from Asterisk
route[FROMFREESWITCH] {
	if(ds_is_from_list("2")){		

                xdbg("message sent from freeswitch_2n");
		return 1;
	}

	if(ds_is_from_list()){
			xdbg("message sent from freeswitchn");
			return 1;
	}

	if($si== $sel(cfg_get.freeswitch.bindip)){
	
		xdbg("message sent from freeswitch ok---n");

		return 1;
	}

	if (src_port age sent from port 5260n");
		return 1;
	}
	
	if (src_ip == 127.0.0.1){

		xdbg("message sent from ip localhostn");
		return 1;
	}


	if (src_ip == 172.17.0.1){

		xdbg("message sent from ip 172.17.0.2n");
		return 1;
	}

	xdbg("message sent from other port:, src_port, $si, $sp");

	return -1;
} 
#!endif

# Routing to FS
route[CALLS] {
	if(!is_method("INVITE")){
		return;
	}	
	if(is_method("INVITE")){
		#!ifdef WITH_FREESWITCH
			if(route(FROMFREESWITCH))
				return 1;
		#!endif
	}

	/*
	$du = "sip:"   $sel(cfg_get.freeswitch.bindip)   ":"
			  $sel(cfg_get.freeswitch.bindport);
	*/
	# Billing Code	
        route(LOADBALANCE);
}

#!ifdef WITH_LOADBALANCE
route[LOADBALANCE] {
   
        if(!ds_select_dst("2", "4"))
        {
                xdbg("No destination available!n");
                send_reply("404", "No destination lbn");
                exit;
        }
        xdbg("Routing call to <$ru> via <$du>n");

	# save callee ID
	$avp(callee) = $rU;

        #t_set_fr(0,2000);
        #t_on_failure("MANAGE_FAILURE");
        //forward();

	# Relay the request:
	//if (!t_relay()) {
	//	send_reply("503", "Service not available");
	//	exit;
	//};
	t_on_failure("RTF_DISPATCH");
	route(RELAY);

        //t_on_failure("RTF_DISPATCH");  
        //set_forward_no_connect();

        exit();
}

# Sample failure route
failure_route[RTF_DISPATCH] {
	if (t_is_canceled()) {
		exit;
	}
	# next DST - only for 500 or local timeout
	if (t_check_status("500")
			or (t_branch_timeout() and !t_branch_replied()))
	{
		if(ds_next_dst())
		{
			t_on_failure("RTF_DISPATCH");
			route(RELAY);
			exit;
		}
	}
}
#!endif

kamailio.cfg配置文件中,主要修改两个点:

1、转发呼叫给FS;

2、对从FS转回来的报文,不能做鉴权,需要在AUTH中修改逻辑:

代码语言:javascript复制
route[AUTH] {
#!ifdef WITH_AUTH

#!ifdef WITH_IPAUTH
	if((!is_method("REGISTER")) && allow_source_address()) {
		# source IP allowed
		return;
	}
#!endif

	#!ifdef WITH_FREESWITCH
	if(route(FROMFREESWITCH)){
                log("route from freeswitchn");
		return 1;
        }
	#!endif
	
}


# User location service
route[LOCATION] {
	if(is_method("INVITE") && (!route(FROMFREESWITCH))) {	
		route(CALLS);
		exit;
	}	
	
}	

freeswitch和kamailio容器的启动方式不同,产生了好些问题,使用host模式启动就没有这么多问题了!

代码语言:javascript复制
开始使用默认模式启动:
docker  run  -d  --net=host   -p 10100:22 -p  5060:5060 -p  5061:5061 -p  5260:5260 -p  5261:5261 -p  5260:5260/udp -p  5261:5261/udp  -p 5067:5067 -p  5060:5060/udp -p  5061:5061/udp -p 5067:5067/udp -p 5080:5080/tcp -p 5080:5080/udp -p 8021:8021/tcp -p 7443:7443/tcp  -p  49000-49900:49000-49900/udp --name freeswitch_run_v30 -v /home/lyz/work:/mnt/work  --privileged=true freeswitch:v50 "/usr/sbin/init" --storage-opt size=100G

#host模式启动
docker  run  -d  --net=host  --name freeswitch_run_v30 -v /home/lyz/work:/mnt/work  --privileged=true freeswitch:v50 "/usr/sbin/init" --storage-opt size=100G

主要参考:

代码语言:javascript复制
https://www.kamailio.org/wiki/cookbooks/5.5.x/core

https://ov500.openvoips.org/documentation/installation/

http://kb.asipto.com/freeswitch:kamailio-3.3.x-freeswitch-1.2.x-sbc
https://blog.csdn.net/qq_41681715/article/details/106633315

0 人点赞