当前位置: 首页 > news >正文

模拟SIP终端向Freeswitch注册用户

1、简介

使用go语言编写一个程序,模拟SIP-T58终端在Freeswitch上注册用户

2、思路

  • 以客户端向服务端Freeswitch发起REGISTER请求,告知服务器当前的联系地址
  • 构造SIP REGISTER请求
  1. 创建UDP连接,连接到Freeswitch的5060端口
  2. 发送初始的REGISTER请求,不带认证
  3. 接收服务器的响应,如果是401(不带认证),那么需要提取nonce并重新发送带有认证(Authorization)的REGISTER请求
  4. 处理服务器返回的响应,确认注册成功

3、实现过程

  • 发送初始的REGISTER请求,此时没有认证头,服务器将会返回401,并且带上WWW-Authenticate头字段

  • 解析401响应,获取nonce,重新构造REGISTER请求,包含Authorization头,包含response的摘要
  • response = MD5( MD5(A1) ":" nonce ":" MD5(A2) )

    其中A1是 username:realm:password,A2是 METHOD:uri。

    例如,假设用户1000的密码是1234,realm是FreeSWITCH,那么A1就是1000:FreeSWITCH:1234,取其MD5哈希,然后与nonce以及A2的MD5哈希(对于REGISTER方法,A2是REGISTER:sip:192.168.0.31)结合,再进行一次MD5计算。

  • 接下来,构建Authorization头部:

    Authorization: Digest username="1000", realm="FreeSWITCH", nonce="...", uri="sip:192.168.0.0", response="...", algorithm=MD5

  1. 创建UDP套接字,绑定到到本机地址
  2. 生成必要的SIP头部字段,客户端生成唯一的Call-ID,并且CSeq序号每次递增
  3. 处理网络通信,发送和接收UDP数据
  4. 解析服务器的响应,提取nonce等信息
  5. 计算response摘要,构造第二个REGISTER请求

4、如何解析服务器的响应

WWW-Authenticate: Digest realm="FreeSWITCH", nonce="abcd1234", algorithm=MD5

需要从该头中提取realm和nonce的值。

处理这些字符串可能需要字符串分割和提取,或者使用正则表达式。

5、定义变量

freeswitchIP := 192.168.0.0

sipUser := "1000"

password := "123456"

localPort := 5061

创建UDP连接

serverAddr,err := net.ResolveUDPAddr("udp",freeswitchIP+":5061")

if err != nil{

  log.Fatal(err)

}

系统分配本机地址

localAddr,err := net.ResolveUDPAddr("udp",localhostIP+":0")

conn,err := net.DialUDP("udp",localAddr,serverAddr)

if err != nil{

        log.Fatal(err)

}

defer conn.Close()

生成Call-ID,CSeq,branch

callID := generateCallID()

cseq := 1

branch := generateBranch()//z9hG4bK + 随机字符

生成初始的REGISTER请求

registerRequest := fmt.Sprintf(

"REGISTER sip:%s SIP/2.0\r\n"+

"Via:SIP/2.0/UDP %s:%d;branch=%s\r\n"+

"Max-Forwards:70\r\n"+

"From:<sip:%s@%s>;tag=%s\r\n"+

"To:<sip:%s@%s>\r\n"+

"Call-ID:%s\r\n"+

"CSeq:%d REGISTER"+

"Contact:<sip:%s@%s:%d>\r\n"+

"Expires:%d\r\n"+

"Context-Length:0\r\n\r\n",

freeswitchIP,localhostIP,localAddr.Port,branch,

sipUser,FreeswitchIP,generateTag(),

sipUser,freeswitchIP,

CallID,

cseq,

sipUser,localIP,localPort,

3600,

)

相关文章:

  • 一键部署自己的私域直播
  • 具身系列——PPO算法实现CartPole游戏(强化学习)
  • operator 可以根据需要重载 == 运算符进行比较
  • Cadence高速系统设计工具
  • 0基础 | STM32 | TB6612电机驱动使用
  • DeepSeek辅助学术写作之提交和出版以及评审过程分析提示词分享祝你顺利毕业~
  • 肥胖风险的多类预测——CatBoost模型的89%
  • Y1——树状数组入门
  • 每天一道面试题@第五天
  • 推理能力:五一模型大放送
  • C# 运算符重载深度解析:从基础到高阶实践
  • 第3章 Python 3 基础语法001
  • 大模型:解码人工智能的算力革命与边界突破
  • Go反射-通过反射调用结构体的方法(带入参)
  • Spring 容器相关的核心注解​
  • xLua笔记
  • 【2025年】MySQL面试题总结
  • 【Java学习】关于springBoot的自动配置和起步依赖
  • 【深度学习-Day 4】掌握深度学习的“概率”视角:基础概念与应用解析
  • re题(53)BUUCTF-[ACTF新生赛2020]SoulLike
  • 上海一中院一审公开开庭审理被告人胡欣受贿案
  • 市场监管总局通报民用“三表”专项检查结果
  • 国铁集团:铁路五一假期旅客发送量累计已超1亿人次
  • 德雷克海峡发生7.4级地震,震源深度10千米
  • 一周文化讲座|那些年的年青人
  • 年轻人能为“老有意思”做点什么