默认情况下,拨打内部用户时,freeswitch需要该用户注册了才能对其发起呼叫,否则会提示-ERR USER_NOT_REGISTERED

如果使用wireshark等工具,可以在本机使用voip终端工具注册,抓包观察一下SIP报文。

注:如果mac上首次使用wireshark时,可能会遇到 you don't have permission to capture on that device mac 之类的权限问题,可参考网友“水麒麟灬”的文章解决。

通过抓包,可以看到大致过程如下:

这4次的报文内容类似下面这样:

1、第1次REGISTER

Frame 1: 650 bytes on wire (5200 bits), 650 bytes captured (5200 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101
User Datagram Protocol, Src Port: 5060, Dst Port: 5070
Session Initiation Protocol (REGISTER)
Request-Line: REGISTER sip:192.168.7.101:5070;transport=UDP SIP/2.0
Message Header
Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z-;rport
Transport: UDP
Sent-by Address: 192.168.7.101
Sent-by port: 5060
Branch: z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z-
RPort: rport
Max-Forwards: 70
Contact: <sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5>;transport=UDP
To: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP
From: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61
Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.
[Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.]
CSeq: 1 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO
User-Agent: Zoiper rev.1809
Allow-Events: presence
Content-Length: 0

首次注册请求时,并未带任何用户名/密码之类的认证信息。 

2、FreeSwitch返回了401

Frame 2: 718 bytes on wire (5744 bits), 718 bytes captured (5744 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101
User Datagram Protocol, Src Port: 5070, Dst Port: 5060
Session Initiation Protocol (401)
Status-Line: SIP/2.0 401 Unauthorized
Message Header
Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z-;rport=5060
Transport: UDP
Sent-by Address: 192.168.7.101
Sent-by port: 5060
Branch: z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z-
RPort: 5060
From: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61
To: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=p8878HBS6XDrB
Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.
[Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.]
CSeq: 1 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
WWW-Authenticate: Digest realm="192.168.7.101", nonce="84af446e-92ed-418b-96c4-4ad9fee55771", algorithm=MD5, qop="auth"
Authentication Scheme: Digest
Realm: "192.168.7.101"
Nonce Value: "84af446e-92ed-418b-96c4-4ad9fee55771"
Algorithm: MD5
QOP: "auth"
Content-Length: 0

注意22行的WWW-Authenticate,服务器返回了认证需要的一些信息:realm/nonce/algoritthm/qop,大致可以看出要求使用MD5算法,让Voip客户端根据服务端返回的信息,算一个digest值提交上来完成校验。

3、第2次REGISTER

Frame 3: 904 bytes on wire (7232 bits), 904 bytes captured (7232 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101
User Datagram Protocol, Src Port: 5060, Dst Port: 5070
Session Initiation Protocol (REGISTER)
Request-Line: REGISTER sip:192.168.7.101:5070;transport=UDP SIP/2.0
Message Header
Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z-;rport
Transport: UDP
Sent-by Address: 192.168.7.101
Sent-by port: 5060
Branch: z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z-
RPort: rport
Max-Forwards: 70
Contact: <sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5>;transport=UDP
Contact URI: sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5
Contact parameter: transport=UDP
To: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP
SIP to display info: "jimmy"
SIP to address: sip:1000@192.168.7.101:5070
SIP to address User Part: 1000
SIP to address Host Part: 192.168.7.101
SIP to address Host Port: 5070
From: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61
SIP from display info: "jimmy"
SIP from address: sip:1000@192.168.7.101:5070
SIP from address User Part: 1000
SIP from address Host Part: 192.168.7.101
SIP from address Host Port: 5070
SIP from tag: e45e4f61
Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.
[Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.]
CSeq: 2 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO
User-Agent: Zoiper rev.1809
[truncated]Authorization: Digest username="1000",realm="192.168.7.101",nonce="84af446e-92ed-418b-96c4-4ad9fee55771",uri="sip:192.168.7.101:5070;transport=UDP",response="de6d3ab9e4a984d1a7a62d69cd00a31a",cnonce="c7dafa660149cc55",nc=00000
Authentication Scheme: Digest
Username: "1000"
Realm: "192.168.7.101"
Nonce Value: "84af446e-92ed-418b-96c4-4ad9fee55771"
Authentication URI: "sip:192.168.7.101:5070;transport=UDP"
Digest Authentication Response: "de6d3ab9e4a984d1a7a62d69cd00a31a"
CNonce Value: "c7dafa660149cc55"
Nonce Count: 00000001
QOP: auth
Algorithm: MD5
Allow-Events: presence
Content-Length: 0

可以看到,第2次注册时,37行Authorization 带上了username,uri 以及根据服务端要求,计算出来的response digest,以及客户端的临时cnonce值。

注:如果对digest计算过程感兴趣的同学,可以参考 RFC3261规范及网友的文章

4、FreeSWITCH返回200

Frame 4: 704 bytes on wire (5632 bits), 704 bytes captured (5632 bits) on interface lo0, id 0
Null/Loopback
Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101
User Datagram Protocol, Src Port: 5070, Dst Port: 5060
Session Initiation Protocol (200)
Status-Line: SIP/2.0 200 OK
Message Header
Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z-;rport=5060
Transport: UDP
Sent-by Address: 192.168.7.101
Sent-by port: 5060
Branch: z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z-
RPort: 5060
From: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61
SIP from display info: "jimmy"
SIP from address: sip:1000@192.168.7.101:5070
SIP from address User Part: 1000
SIP from address Host Part: 192.168.7.101
SIP from address Host Port: 5070
SIP from tag: e45e4f61
To: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=QH20aDvv363aQ
SIP to display info: "jimmy"
SIP to address: sip:1000@192.168.7.101:5070
SIP to address User Part: 1000
SIP to address Host Part: 192.168.7.101
SIP to address Host Port: 5070
SIP to tag: QH20aDvv363aQ
Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.
[Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.]
CSeq: 2 REGISTER
Contact: <sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5>;expires=3600
Contact URI: sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5
Contact parameter: expires=3600
Date: Sun, 23 May 2021 10:23:16 GMT
User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Length: 0

FreeSWITCH收到提交过来的认证信息后,进行验证,验证通过后,返回200。(注:如校验失败,仍会返回401)。

大致了解注册过程后,下面来看看SIPp如何测试这个场景:

先写xml文件:reg.xml

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2 <!DOCTYPE scenario SYSTEM "sipp.dtd">
3
4 <scenario name="register">
5 <send retrans="500">
6 <![CDATA[
7 REGISTER sip:[remote_ip] SIP/2.0
8 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
9 Max-Forwards: 70
10 Contact: sip:[field0]@[local_ip]:[local_port]
11 To: [field0] <sip:[field0]@[remote_ip]:[remote_port]>
12 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[call_number]
13 Call-ID: [call_id]
14 CSeq: 1 REGISTER
15 Expires: 3600
16 User-Agent: SIPp
17 Content-Length: 0
18 ]]>
19 </send>
20
21 <recv response="401" auth="true">
22 </recv>
23
24 <send retrans="500">
25 <![CDATA[
26 REGISTER sip:[field0]@[remote_ip]:[remote_port] SIP/2.0
27 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
28 Max-Forwards: 70
29 Contact: sip:[field0]@[local_ip]:[local_port]
30 [field1]
31 To: [field0] <sip:[field0]@[remote_ip]:[remote_port]>
32 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[call_number]
33 Call-ID: [call_id]
34 CSeq: 2 REGISTER
35 Expires: 3600
36 User-Agent: SIPp
37 Content-Length: [len]
38 ]]>
39 </send>
40
41 <recv response="200">
42 </recv>
43
44 <!-- Keep the call open for a while in case the 200 is lost to be -->
45 <!-- able to retransmit it if we receive the 200 again. -->
46 <timewait milliseconds="500"/>
47
48 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
49 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
50 </scenario>

第1次REGISTER的SIP内容好写,但是第2次时,最终计算出来的response md5值如何处理,难道要自己算吗?当然不用!

SIPp已经按照规范,内部实现了这个digest的计算过程,只需要参考SIPp文档 中的“SIP authentication”,第2次发起REGISTER时,把username放在单独的一行中即可(xml中的第30行)

最终执行时, SIPp会根据类似下面的csv文件:reg.csv

SEQUENTIAL
1000;[authentication username=1000 password=1234]
1001;[authentication username=1001 password=1234]
1002;[authentication username=1002 password=1234]
1003;[authentication username=1003 password=1234]
1004;[authentication username=1004 password=1234]
1005;[authentication username=1005 password=1234]
1006;[authentication username=1006 password=1234]
1007;[authentication username=1007 password=1234]
1008;[authentication username=1008 password=1234]
1009;[authentication username=1009 password=1234]
1010;[authentication username=1010 password=1234]
1011;[authentication username=1011 password=1234]
1012;[authentication username=1012 password=1234]
1013;[authentication username=1013 password=1234]
1014;[authentication username=1014 password=1234]
1015;[authentication username=1015 password=1234]
1016;[authentication username=1016 password=1234]
1017;[authentication username=1017 password=1234]
1018;[authentication username=1018 password=1234]
1019;[authentication username=1019 password=1234]

动态从该文件中,取出username及password,然后计算出digest值,发给FreeSWITCH。

运行一下:

sipp 192.168.7.101:5070 -sf reg.xml -inf reg.csv -d 1000 -trace_err -m 20  -aa

注:其中192.168.7.101:5070 为FreeSWITCH的ip和端口。

顺利的话,会看出类似上面的结果 ,freeswitch中也可以通过命令验证:

可以看到20个用户注册成功,挑其中1个用户1001看下详情:

EXP括号里的内容为过期时间,Auth-User为用户名,Agent可以看到是通过是SIPp注册的。

最后提醒一下:需要注册的用户,必须是FreeSWITCH中创建好的用户,如果不存在的用户,比如:8888

SEQUENTIAL
8888;[authentication username=8888 password=1234]

测试时,FreeSWITCH会返回403

SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-48936-1-2
From: 8888 <sip:8888@192.168.7.101:5061>;tag=1
To: 8888 <sip:8888@192.168.7.101:5070>;tag=07jyp9tgU8r2c
Call-ID: 1-48936@192.168.7.101
CSeq: 2 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Length: 0

从FreeSWITCH控制台,也能观察到错误输入:

SIPp测试freeswitch用户注册的更多相关文章

  1. sipp模拟freeswitch分机测试(SIP协议调试)

    1.freeswitch安装 1) 网上很多安装方法都不靠谱,系统版本,各种依赖库一堆问题,下面是验证的可行的. yum install -y http://files.freeswitch.org/ ...

  2. freeswitch嵌入python脚本

    操作系统:debian8.5_x64 freeswitch 版本 : 1.6.8 python版本:2.7.9 开启python模块 安装python lib库 apt-get install pyt ...

  3. Freeswitch 添加可转码的G729编码

    默认情况下Freeswitch自带的G729模块是pass-through-并不支持转码. 不过我们依然有个好奇的心, 所以我们决定添加一个支持G729转码的模块到Freeswitch. 1. 下载m ...

  4. 开源软交换系统 FreeSwitch 与 Asterisk 比较

    Asterisk 与freeswitch都是流行的开源软交换服务器,Asterisk出现的比较早,大概在1999年开始此项目,应该是最流行的开源软交换服务器,整个社区上下游都已经很成熟. freesw ...

  5. FreeSWITCH Git版本管理

    由于测试FreeSWITCH不同版本的需要,研究了下Git的使用,通过Git来管理所有的版本,方便了测试.以下就总结下具体的使用方法: 其中:git clone ..是现在git仓库:git tag ...

  6. Jmeter接口测试-新用户注册API

    新用户注册 新用户注册的接口是POST /register username/password/password_confirmation 该接口需要提供3个参数,分别是 username 用户名 p ...

  7. Laravel数据库测试的另一种方案-SQLite

    Laravel数据库测试 在测试方面,Laravel内置使用PHPUnit提供了非常方便的解决方案.而对于数据库增删改查的测试,要解决的一个很重要的问题就是如何在测试完成之后,恢复数据库的原貌,例如要 ...

  8. Freeswitch Tutorial

    I. Install Freeswitch 1) FreeSWITCH Explained https://freeswitch.org/confluence/ https://freeswitch. ...

  9. 03- web表单测试

    软件分为 b/s c/s两种架构 表单测试 1.用户注册,登录,信息提交. 2.用户查询商品. 3.用户订购商品. 4.用户查询订单等. 表单测试实例 表单数据添加测试(一) 添加按钮可用,测试点击添 ...

  10. freeswitch简介

    freeswitch简介 freeswitch是开源的,免费的. freeswitch是一款非常好用的电话软交换框架,支持跨平台,扩展性良好,配置灵活. freeswitch可以在很多平台上运行,包括 ...

随机推荐

  1. 校园圈子系统:Uni-app跨端渲染+TP6实时推送核心逻辑与代码

    在TP6中实现实时推送功能,核心逻辑围绕WebSocket服务搭建.用户连接管理.消息路由和性能优化展开.以下是详细的实现步骤和逻辑说明: TP6实时推送核心逻辑 WebSocket服务搭建 使用Wo ...

  2. spring boot迁移计划 第Ⅰ章 --chapter 1. rust hyper 结合rust nacos-client开发nacos网关 part ④ nacos-client

    1. toml依赖 nacos_rust_client = "0.3" local_ipaddress = "0.1" ahash = "0.8&qu ...

  3. MYSQL的API

    1.函数的使用 常用函数(比较,分组,判断等) 截取函数:substring_index(目标字符串,分隔符,序号) 获取时间函数:TIMESTAMPDIFF(格式,开始时间,结束时间) 2.遇到的问 ...

  4. DP 动态规划初识

    前面的 HMM 中参数求解, 都会用到动态规划, 全是各种概率公式, 是有一些抽象, 今天决定举个一波简单的栗子, 帮助理解DP 把一个大问题,不断划分为更小的子问题来求解的这种方式, 就是动态规划. ...

  5. Opencv与Pillow图片操作差异对深度学习的影响

    目前在使用Pytorch训练的深度学习模型算法,大部分由于pillow与torchvision中transforms的优异兼容都会采用Image.open from pillow的方式进行图像数据的读 ...

  6. 【踩坑】VMware Workstation 17.x 中的虚拟机按键反映迟钝

    [踩坑]VMware Workstation 17.x 中的虚拟机按键反映迟钝 目录 [踩坑]VMware Workstation 17.x 中的虚拟机按键反映迟钝 问题描述 笔者环境 解决方法 测试 ...

  7. [VulnHub]DC-3靶场全过程

    DC-3 靶机部署 下载好DC-3,直接导入 可以生成一个mac地址,方便我们确认主机 信息收集 获取靶机ip(arp-scan/nmap) arp-scan -l nmap 192.168.190. ...

  8. EasyExcel读取多个sheet表数据,自定义监听器

    接口 /** * 导入 * * @param file * @return */ @PostMapping("/waitimport") public Result waitImp ...

  9. Android Studio 中 TextView 控件学习

    以下图片都来自于B站视频,仅留作学习记录,方便复习 视频链接 代码练习 <LinearLayout android:layout_width="match_parent" a ...

  10. DeepSeek MOE 代码实现

    前置知识: PyTorch 基础函数操作整理 1. topk 操作 功能: torch.topk 用于返回输入张量中指定维度上的前 k 个最大元素及其对应的索引. 示例代码: import torch ...