问题表现
在经过初始化请求之后,路径发现完成。在这个dialog中所有的请求,正常来ua1和ua2之间的所有请求,都应该经过us1和us2。
如下图所示:
某些时候,ua1可能直接把BYE消息直接发送给ua2, 但是一般ua1和ua2是存在uat网络的,所以这个BYE消息,ua2很可能收不到。
问题的表现就是电话无法正常挂断。
问题分析
- 可能原因1: us1和us2没有做record-route, 导致请求直接根据某个请求的响应消息的Contact头,直接发送了。
- 可能原因2: 某些请求的拓扑隐藏没有做好
拓扑隐藏问题具体分析
假如我们在us1上正确的做了拓扑隐藏,那么ua1的所有收到的响应,它的Contact头的地址都会改成us1的地址。那么ua1是无论如何都获取不到ua2的直接地址的。
但是,假如某个消息处理的不对呢?
- 注意180响应5到6, 其中us1正确的修改了Contact头
- ua1收到180后,立即发送了notify消息
- 如果us1没有正确处理notify的响应的Contact头,us1就会把ua2的Contact信息发送给ua1。有些notify的响应带有Contact头,有些没带有。
- 但是这里会出现一个竞争条件,invite的200ok和notify的200ok,消息到达的顺序,将影响ua2的Contact信息
- 如果ua1后收到invite的200ok, 此时ua1获取ua2的地址是us1
- 如果ua2后收到notify的200ok, 此时ua2获取的ua2的地址就是ua2
- 所以问题的表现可能是有偶现的,这种问题处理其实是比较棘手的
- 当然也是有解决方案的
- 方案1, us1对notify正确处理响应消息Contact, 将其修改成us1
- 方案2,us1直接删除notify响应消息的Contact头