介绍几种OPTIONS检测的方法
概述
日常的VOIP开发中,OPTIONS检测是常用的网络状态检测工具。
OPTIONS原本是作为获取对方能力的消息,也可以检测当前服务状态。正常情况下,UAS收到OPTIONS心跳,直接回复200即可。
与ping不同的是,OPTIONS检测不仅仅针对网络状态,也针对sip server的端口状态进行检测,在VOIP问题定位中更精准。
环境
CentOS release 7.0 (Final)或以上版本
freeswitch v1.10.7
new bing
sipp.3.6.2
sipexer-v1.1.0-linux-amd64
可选方案
freeswitch自带的OPTIONS检测
python脚本
sipp工具
sipexer工具
freeswitch自带的OPTIONS检测
freeswitch自带的OPTIONS检测可以通过配置gateway网关来启动,也可以针对注册的在线用户设置OPTIONS心跳检测,配置方法简单介绍如下。
gateway网关设置。修改conf/sip_profile/external/gw-137.xml
<include>
<gateway name="gw-137">
<param name="realm" value="10.55.55.137:5080"/>
<param name="caller-id-in-from" value="true"/>
<param name="register" value="false"/>
<!--send an options ping every x seconds, failure will unregister and/or mark it down-->
<param name="ping" value="20"/>
<param name="ping-min" value="2"/>
<param name="ping-max" value="3"/>
</gateway>
</include>
针对注册的在线用户设置OPTIONS心跳检测,修改conf/sip_profile/internal.xml
<param name="unregister-on-options-fail" value="true"/>
<!-- Send an OPTIONS packet to all registered endpoints -->
<param name="all-reg-options-ping" value="true"/>
<!-- Send an OPTIONS packet to NATed registered endpoints. Can be 'true' or 'udp-only'. -->
<param name="nat-options-ping" value="true"/>
<param name="registration-thread-frequency" value="30"/>
<param name="ping-mean-interval" value="30"/>
<param name="ping-thread-frequency" value="1"/>
python脚本
github上很多,缺点是需要自己调试,适配符合的场景模式。
下面的脚本是使用new bing自动生成的脚本,未测试仅供参考。
好的,您可以使用Python内置的SIP库`sip`来发送OPTIONS请求。这个库可以在Python 3.7及以上版本中使用。您可以使用以下代码来实现您的需求:
```python
import sip
import sys
def send_options(remoteip, remoteport):
sip.setapi('sip', 2)
from sip import SIPRequest, SIPResponse
from socket import socket, AF_INET, SOCK_DGRAM
import time
# Check if the IP address is valid
try:
socket(AF_INET, SOCK_DGRAM).connect((remoteip, remoteport))
except OSError:
print("Invalid IP address")
return
# Send OPTIONS request
s = socket(AF_INET, SOCK_DGRAM)
s.settimeout(5)
sip_request = SIPRequest('OPTIONS', 'sip:{}:{};transport=udp'.format(remoteip, remoteport), 'SIP/2.0')
sip_request.add_header('Via', 'SIP/2.0/UDP {}:{};branch=z9hG4bK-{}'.format(s.getsockname()[0], s.getsockname()[1], int(time.time())))
sip_request.add_header('From', '<sip:test@{}:{}>;tag=1234'.format(s.getsockname()[0], s.getsockname()[1]))
sip_request.add_header('To', '<sip:test@{}:{}>'.format(remoteip, remoteport))
sip_request.add_header('Call-ID', '{}@{}'.format(int(time.time()), s.getsockname()[0]))
sip_request.add_header('CSeq', '1 OPTIONS')
sip_request.add_header('Contact', '<sip:test@{}:{}>'.format(s.getsockname()[0], s.getsockname()[1]))
sip_request.add_header('Max-Forwards', '70')
s.sendto(bytes(sip_request), (remoteip, remoteport))
# Receive response
try:
data = s.recv(1024)
response = SIPResponse(data.decode())
print("Response received: {}".format(response.status_code))
print(response.headers)
print(response.body)
except Exception as e:
print("Error receiving response: {}".format(e))
```
其中,`send_options()`函数接受两个参数:`remoteip`和`remoteport`。这个函数会发送一个SIP OPTIONS请求到指定的IP地址和端口,并打印响应消息。如果请求失败,则会打印错误消息。
请注意,在使用此代码之前,请确保您已经安装了Python 3.7或更高版本,并且已经安装了`sip`库。
以上内容为new bing自动生成,未经测试。
sipp脚本
配置sipp号码文件call-test.csv,内容如下。
SEQUENTIAL
123456;13712345678;
增加sipp脚本文件uac-options.xml,内容如下。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario name="Basic options UAC">
<send retrans="500">
<![CDATA[
OPTIONS sip:[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
To: [field1] <sip:[field1]@[remote_ip]:[remote_port]>
Call-ID: [call_id]
CSeq: 10 OPTIONS
Max-Forwards: 10
Content-Length: 0
]]>
</send>
<recv response="200" crlf="true">
</recv>
<ResponseTimeRepartition value="10, 20, 30"/>
<CallLengthRepartition value="10, 50, 100"/>
</scenario>
使用sipp命令发起OPTIONS检测
sipp -i 10.55.55.138 -p 6666 -inf call-test.csv -sf uac-options.xml 10.55.55.137:5080 -rp 1000 -r 100 -l 8192 -m 1
可以查看sipp结果是成功或失败。
sipexer
sipexer工具内置OPTIONS功能,只需要简单的参数即可测试。
下载sipexer的发布包,并解压,即可得到sipexer的可执行程序。
wget https://github.com/miconda/sipexer/releases/download/v1.1.0/sipexer-v1.1.0-linux-amd64.tar.gz
tar -zxvf sipexer-v1.1.0-linux-amd64.tar.gz
ll
-rwxr-xr-x. 1 admin admin 8637840 6月 30 16:57 sipexer
测试,从本地发送OPTIONS检测到10.55.55.137:5080。
./sipexer sip:10.55.55.137:5080
[info] [sipexer.go:1578] main.SIPExerDialogLoop(): local socket address: 10.55.55.138:45585 (udp)
[info] [sipexer.go:1579] main.SIPExerDialogLoop(): local via address: 10.55.55.138:45585
[info] [sipexer.go:1580] main.SIPExerDialogLoop(): sending to udp 10.55.55.137:5080: [[---
OPTIONS sip:10.55.55.137:5080 SIP/2.0
Via: SIP/2.0/UDP 10.55.55.138:45585;rport;branch=z9hG4bKSG.29529ee2-2cad-47b6-b68e-d26cdccbc940
From: <sip:alice@localhost>;tag=d2c84867-447e-4d94-9216-bfb4c81d7441
To: <sip:bob@localhost>
Call-ID: 8b74f427-6458-407c-ad80-d52157041eee
CSeq: 596582 OPTIONS
Date: Mon, 03 Jul 2023 13:56:33 CST
User-Agent: SIPExer v1.1.0
Max-Forwards: 10
Content-Length: 0
[info] [sipexer.go:1582] main.SIPExerDialogLoop(): ---]]
[info] [sipexer.go:1633] main.SIPExerDialogLoop(): response-received: from=10.55.55.137:5080 bytes=597 data=[[---
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.55.55.138:45585;rport=45585;branch=z9hG4bKSG.29529ee2-2cad-47b6-b68e-d26cdccbc940
From: <sip:alice@localhost>;tag=d2c84867-447e-4d94-9216-bfb4c81d7441
To: <sip:bob@localhost>;tag=5Dta8ca41BQBF
Call-ID: 8b74f427-6458-407c-ad80-d52157041eee
CSeq: 596582 OPTIONS
Contact: <sip:10.55.55.137:5080>
User-Agent: FreeSWITCH-mod_sofia/1.6.19~64bit
Accept: application/sdp
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: timer, path, replaces
Allow-Events: talk, hold, conference, refer
Content-Length: 0
[info] [sipexer.go:1635] main.SIPExerDialogLoop(): ---]]
测试成功,OPTIONS正常收到200 OK响应。
总结
OPTIONS心跳检测在voip的应用过程中还是挺重要的,对于线路和sip应用的正常检测必不可少,配合zabbix等监控平台可以及时有效的发现问题。
不同的工具使用方式各有不同,需要根据实际场景确定。
空空如常
求真得真