resiprocate 之repro注册
repro为resiprocate 提供的代理服务,可以直接运行,我们可以参考他,来实现自己的sip服务,下面分析一下repro关于digest流程的处理。
找到工程reprolib的ReproServerAuthManager 类,处理digest认证再此类完成。
首先进入,这里返回true 表示digest 认证
ServerAuthManager::AsyncBool
ReproServerAuthManager::requiresChallenge(const SipMessage& msg)
{resip_assert(msg.isRequest());if(!mAclDb.isRequestTrusted(msg)){return ServerAuthManager::requiresChallenge(msg);}else{return False;}
}
然后进入requestCredential函数
void
ReproServerAuthManager::requestCredential(const Data& user, const Data& realm, const SipMessage& msg,const Auth& auth,const Data& transactionId )
{// Build a UserAuthInfo object and pass to UserAuthGrabber to have a1 password filled inUserAuthInfo* async = new UserAuthInfo(user,realm,transactionId,&mDum);std::auto_ptr<ApplicationMessage> app(async);mAuthRequestDispatcher->post(app);
}
这个函数的作用是获取A1值,A1说明如下
采用MD5算法:A1=(user):(realm):(password)
我们自己开发服务的时候,可以直接在这里获取A1的值,反馈给dum,
repro 在UserAuthGrabber::process函数获取A1的值,其实就是从数据库里面把A1的值拿出来。
UserAuthGrabber::process(resip::ApplicationMessage* msg)
{repro::UserInfoMessage* uinf = dynamic_cast<UserInfoMessage*>(msg); // auth for repro's DigestAuthenticatorif (uinf){uinf->mRec.passwordHash = mUserStore.getUserAuthInfo(uinf->user(), uinf->realm());uinf->setMode(resip::UserAuthInfo::RetrievedA1);DebugLog(<< "Grabbed user info for " << uinf->user() << "@" << uinf->realm() << " : " << uinf->A1());return true;}resip::UserAuthInfo* uainf = dynamic_cast<resip::UserAuthInfo*>(msg); // auth for DUM's ServerAuthManagerif (uainf){uainf->setA1(mUserStore.getUserAuthInfo(uainf->getUser(), uainf->getRealm()));if (uainf->getA1().empty()){uainf->setMode(resip::UserAuthInfo::UserUnknown);}DebugLog(<< "Grabbed user info for " << uainf->getUser() << "@" << uainf->getRealm() << " : " << uainf->getA1());return true;}repro::PresenceUserExists* pue = dynamic_cast<repro::PresenceUserExists*>(msg); // user exists query for Presence serverif (pue){pue->setUserExists(!mUserStore.getUserInfo(UserStore::buildKey(pue->getUser(), pue->getDomain())).user.empty());DebugLog(<< "Checking existence for " << pue->getUser() << "@" << pue->getDomain() << " : user " << (pue->getUserExists() ? "exists" : "does not exist"));return true;}WarningLog(<< "Did not recognize message type...");return false;
}
获取A1值之后调用
mStack->post
投递给协议栈,即可完成注册流程的服务端开发。
queueToStack = mWorker->process(msg);if(queueToStack && mStack){StackLog(<<"async work done, posting to stack");// Post to stack instead of directly to TU, since stack does// some safety checks to ensure the TU still exists before postingmStack->post(std::auto_ptr<resip::ApplicationMessage>(msg));}
****************-------我是风格线--------****************************
用海康摄像机,测试注册功能,如下图,发现一个大问题,当sip用户名和sip用户认证ID填写一样时,可以认证通过
但是当这两者不一样时,认证失败,抓包显示未知用户。
通过阅读源码,发现在校验结束后,还校验了from字段的用户名和认证用户名是否一样,强制修改为return true后,认证通过。
为什么一定要from字段的用户名和认证用户名一样呢?不得而知。
bool
ServerAuthManager::authorizedForThisIdentity(const resip::Data &user, const resip::Data &realm, resip::Uri &fromUri)
{// !rwm! good enough for now. TODO eventually consult a database to see what// combinations of user/realm combos are authorized for an identity// First try the form where the username parameter in the auth// header is just the username component of the fromUri//if ((fromUri.user() == user) && (fromUri.host() == realm))return true;// Now try the form where the username parameter in the auth// header is the full fromUri, e.g.// Proxy-Authorization: Digest username="user@domain" ...//if (fromUri.getAorNoPort() == user)return true;// catch-all: access deniedreturn true;
}
附上抓包截图
*****************************************resip注册处理流程******************************************
今天遇到了sip注册发生了405的错误
查明原因,注册管理,需要设置RegistrationPersistenceManager类,由于我没有设置,所以返回405失败。
增加RegistrationPersistenceManager属性
InMemorySyncRegDb* pRegDB = new InMemorySyncRegDb(0);mDum->setRegistrationPersistenceManager(pRegDB);
另外发现一个调试的好方法:找到错误码的对应类,打上断点,基本上就可以处理基本的错误。
resiprocate 之repro注册相关推荐
- resiprocate 之repro使用
repro 是sip代理的程序,可以直接运行,我们可以通过这个程序对resiprocate进行研究. 编译完后,可以直接运行: 输入网址 127.0.0.1:5080进行配置 点击login进行配置. ...
- java后端内部面试题
21.什么时候不要使用索引? 1. 经常增删改的列不要建立索引: 2. 有大量重复的列不建立索引: 3. 表记录太少不要建立索引. 22.说说什么是 MVCC? 多版本并发控制(MVCC=Multi- ...
- reSIProcate实现GB28181服务——注册、心跳、已注册用户存储、catalog、invite、info、subscribe
为什么是reSIProcate 我最初使用的是exosip2,但是个人感觉作为sipserver并不是很合适,因此找到了reSIProcate, 代码封装很好,就是资料比较少,在阅读demo和源码后先 ...
- 开源协议栈 rlc rrc_从ReSIProcate SIP协议栈库到GB28181
背景 最近Gemfield团队在使用其它部门的某三方库进行GB28181协议的适配,然后在Docker化的过程中遇到了问题:SIP信令在Docker网络上无法正常工作.具体来说,当服务部署在宿主机(1 ...
- ReSIProcate源码目录下功能说明
1.basicCall,basicMessage,basicRegister,resip_test测试用的 2.db_static Sleepy Cat开发的Berkeley DB 3.dum为Dia ...
- ReSIProcate环境搭建
1首先下载resiprocate-1.6 2取消resiprocate-1.6目录的只读属性 3然后使用Visual Studio 2008打开resiprocate-1.6下的reSIProcate ...
- etcd 笔记(09)— 基于 etcd 实现微服务的注册与发现
1. 服务注册与发现基本概念 在单体应用向微服务架构演进的过程中,原本的巨石型应用会按照业务需求被拆分成多个微服务,每个服务提供特定的功能,也可能依赖于其他的微服务.此时,每个微服务实例都可以动态部署 ...
- SpringCloud Alibaba微服务实战(二) - Nacos服务注册与restTemplate消费
说在前面 基础环境搭建,理论,请看上一篇,在这就不扯理论了,直接上代码. 项目结构 代码实现 第一步:在父pom的项目中引入dependencyManagement 在引入父pom之前咱们先来回顾下d ...
- 在Relay中注册新TVM算子
在Relay中注册新TVM算子 在本文件中,将介绍在Relay中注册新TVM算子所需的步骤.将以添加累积算子的PR为例.PR本身建立在另一个PR的基础上,该PR添加了一个累积和运算. 注册新算子需要几 ...
最新文章
- Spinnaker部署
- python归并排序 分词_python-归并排序
- Linux 网络层收发包流程及 Netfilter 框架浅析
- 字符设备驱动基础篇1——简单的驱动源码分析
- HTML5中的Web Notification桌面通知(右下角提示)
- Windows启动管理器
- 总线与微命令实验总结_【干货】总线制?分线制?分不清楚看看这篇文章就知道了...
- 浏览器展示CSS伪类的动画和过渡效果应用
- 2000年一元钱牡丹图案现在值钱吗?
- 拓端tecdat|R语言k-Shape时间序列聚类方法对股票价格时间序列聚类
- 《穿越计算机的迷雾》读书笔记四
- 微信小程序或微信网页里关注公众号
- ARM汇编之合法立即数的快速判断方法
- mvc:annotation-driven注解的作用
- ide 安装eval reset插件
- postgreSql版的occurs函数
- iOS:仿微信朋友圈的实现
- 实时音视频聊天中的延时问题一篇就够,低延时场景及优化
- html怎么做整个屏幕的遮罩,html遮罩实现
- 2021年小红书品牌经典爆文拆解