SIP是一个对等的协议,类似P2P。它和HTTP不一样,其不是客户端服务器结构的;也不像传统电话那样必须有一个中心的交换机,它可以在不需要服务器的情况下进行通信,只要通信双方都彼此知道对方地址(或者只有一方知道另一方的地址)即可,这种情况称为点对点通信。
Bob给Alice发送一个INVITE请求,说“Hi,一起吃饭吧…”,Alice说“好的,OK”,电话就接通了。
UA用户代理
在SIP网络中,Alice和Bob都称为用户代理(User Agent,UA)。UA是在SIP网络中发起或响应SIP处理的逻辑实体。UA是有状态的,也就是说,它维护会话(或称对话)的状态。UA有两种:一种是UAC(UA Client),它是发起SIP请求的一方,比如图7-1中的Bob;另一种是UAS(UA Server),它是接受请求并发送响应的一方,比如图7-1中的Alice。由于SIP是对等的,当Alice呼叫Bob时,Alice就称为UAC,而Bob则实现UAS的功能。一般来说,UA都会实现上述两种功能。
设想Bob和Alice是经人介绍认识的,而他们还不熟悉,Bob想请Alice吃饭就需要一个中间人(M)传话,而这个中间人就叫代理服务器(Proxy Server)。还有另一种中间人称为重定向服务器(Redirect Server),它以类似于这样的方式工作──中间人M告诉Bob,我也不知道Alice在哪里,但我爱人知道,要不然我告诉你我爱人的电话,你直接问她吧,我爱人叫W。这样,M就成了一个重定向服务器(把Bob对他的请求重定向到他的爱人,这样Bob接下来要直接联系他的爱人),而他的爱人W是真正的代理服务器。这两种服务器都是UAS,它们主要是提供一对欲通话的UA之间的路由选择功能。
还有一种UAS称为注册服务器。试想这样一种情况:Alice还是个学生,没有自己的手机,但它又希望Bob能随时找到她,于是当她在学校时就告诉中间人M说她在学校,如果有事找她可以打宿舍的固定电话;如果她要回家,也通知M说有事打家里电话;或许某一天她要去姥姥家,也要把她姥姥家的电话告诉M。总之,只要Alice换一个新的位置,它就要向M重新“注册”,以让M能随时找到她,这时候M就相当于一个注册服务器。
背靠背用户代理
还有一种特殊的UA称为背靠背用户代理(Back-to-Back UA,B2BUA)。需要指出,其实RFC 3261并没有定义B2BUA的功能,它只是一对UAS和UAC的串联。FreeSWITCH就是一个典型的B2BUA,事实上,B2BUA的概念会贯穿本书始终,。
背靠背代理实际就是一端连接UAS 一端连接UAC
SBC
边界会话控制器(Session Border Controller,SBC)。它主要位于一堆SIP服务器的边界,用于隐藏内部服务器的拓扑结构、抵御外来攻击等。SBC可能是一个代理服务器,也可能是一个B2BUA。
基本方法

SIP必须包含的头域
配置
# cat sip-profile.xml<profile name="sip-profile"><gateways></gateways><aliases></aliases><domains><domain name="all" alias="false" parse="true"/></domains><settings><param name="debug" value="0"/><param name="shutdown-on-fail" value="true"/><param name="sip-trace" value="yes"/><param name="sip-capture" value="$${FS_SIP_CAPTURE}"/><param name="rfc2833-pt" value="101"/><param name="dialplan" value="XML"/><param name="context" value="sip-dialplan"/><param name="dtmf-duration" value="2000"/><param name="rtp-timer-name" value="soft"/><param name="local-network-acl" value="localnet.auto"/><param name="manage-presence" value="false"/><param name="inbound-codec-prefs" value="OPUS,G722,PCMU,PCMA,H264,VP9,VP8"/><param name="outbound-codec-prefs" value="OPUS,G722,PCMU,PCMA,H264,VP9,VP8"/><param name="nonce-ttl" value="60"/><param name="auth-calls" value="false"/><param name="disable-transcoding" value="true"/><param name="inbound-late-negotiation" value="true"/><param name="inbound-zrtp-passthru" value="false"/><param name="rtp-ip" value="$${local_ip_v4}"/><param name="sip-ip" value="$${local_ip_v4}"/><param name="ext-rtp-ip" value="$${FS_EXT_RTP_IP}"/><param name="ext-sip-ip" value="$${FS_EXT_SIP_IP}"/><param name="rtp-timeout-sec" value="30"/><param name="rtp-hold-timeout-sec" value="1800"/><param name="sip-port" value="$${FS_SIP_PORT}"/><param name="ws-binding" value=":$${FS_WS_PORT}"/><param name="tls" value="true"/><param name="tls-only" value="false"/><param name="tls-bind-params" value="transport=tls"/><param name="tls-sip-port" value=":$${FS_TLS_PORT}"/><param name="wss-binding" value=":$${FS_WSS_PORT}"/><param name="tls-cert-dir" value="/etc/freeswitch/tls"/><param name="tls-passphrase" value=""/><param name="tls-verify-date" value="false"/><param name="tls-verify-policy" value="none"/><param name="tls-verify-depth" value="10"/><param name="tls-verify-in-subjects" value=""/><param name="tls-version" value="$${sip_tls_version}"/></settings></profile>
查看网关状态
> sofia statusName Type Data State=================================================================================================sip-profile profile sip:mod_sofia@172.17.0.2:5060 RUNNING (0)sip-profile profile sip:mod_sofia@172.17.0.2:5061 RUNNING (0) (TLS)sip-profile::example.com gateway sip:joeuser@example.com NOREG=================================================================================================
呼叫
注册用户
在 /usr/local/freeswitch/conf/directory/default/ 下有默认的 1000-1019 共 20 个帐号,可以
通过 copy 并修改其中的 user_id 来实现增加新的号码。
免费软电话
| yate | http://docs.yate.ro/wiki/Download |
|---|---|
| linphone | http://www.linphone.org/ |

选择助手
使用sip账户

查看注册信息
> sofia status profile internal regRegistrations:=================================================================================================Call-ID: sR6S-T8urrUser: 1000@192.168.0.3Contact: "1000" <sip:1000@114.251.166.156:10269;transport=udp>Agent: Linphone Desktop/4.2.2 (macOS 10.15, Qt 5.14.2) LinphoneCore/4.4.0-13-gc99cb9c88Status: Registered(UDP)(unknown) EXP(2020-11-18 11:17:17) EXPSECS(2725)Ping-Status: ReachablePing-Time: 0.00Host: JDIP: 114.251.166.156Port: 10269Auth-User: 1000Auth-Realm: 114.67.95.29MWI-Account: 1000@192.168.0.3Total items returned: 1=================================================================================================
查看5060 端口占用情况
lsof -i udp:5060COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMElinphone 1325 baxiang 32u IPv6 0xd2700171f2ffb53b 0t0 UDP *:sip
originate
FreeSWITCH中使用originate命令发起一次呼叫
originate user/1000 &echo
呼叫字符串
“user/1000”称为呼叫字符串(Dial String,有时也叫CallURL)。“user”是一种特殊的呼叫字符串,在后面我们还会看到其他的呼叫字符串。
外呼SIP网关
如果你在某个运营商拥有SIP账号,你就可以配置上拨打外部电话了。该SIP账号(或提供该账号的设备)在 FreeSWITCH 中称为SIP网关(Gateway)。添加一个网关只需要在 etc/freeswitch/sip_profiles/external/ 创建一个XML文件,名字可以随便起,如gw1.xml。
<gateway name="gw1"><param name="realm" value="SIP服务器地址,可以是IP或IP:端口号"/><param name="username" value="SIP用户名"/><param name="password" value="密码"/><param name="register" value="true" /></gateway>
如果你的SIP网关还需要其它参数,可以参阅同目录下的 example.xml,但一般来说上述参数就够了。你可以重启 FreeSWITCH,或者执行以下命令使用之生效。
freeswitch@acs> sofia profile external rescan reloadxml
然后显示一下状态:
freeswitch@acs > sofia status
如果显示 gateway gw1 的状态是 REGED ,则表明正确的注册到了网关上。你可以先用命令试一下网关是否工作正常:
uuid_bridge
Originate Call without Registration
/usr/local/freeswitch/bin/fs_cli -x "originate {sip_auth_username=908504300006,sip_auth_password=Ytungftr54ey7}sofia/external/905999999999@0.0.0.0 &echo"
日志追踪
sofia profile external siptrace onsofia profile internal siptrace on
参考
http://www.coder55.com/article/7187
https://www.cnblogs.com/yjmyzz/p/zoiper-and-yateclient-turotial.html
https://blog.csdn.net/wlg9527/article/details/106247292
https://discuss.ptorch.com/article/44.html
