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

比较Kamailio和OpenSIPS的重写contact函数

Kamailio:调用set_contact_alias()之后,在原有的contact的后面增加参数,具体地说,就是网络地址,网络端口和transport,好处是收到后续请求之时可以恢复原有contact的内容(当然也有坏处,就是增加参数之后导致包大,可能超过MTU)

OpenSIPS:调用fix_nated_contact()之后,用网络地址和网络端口直接覆盖了在原有的contact,那么当收到后续请求时不太可能恢复原有contact的内容。窃以为,一定要慎重

比如,下图所示,OpenSIPS就不要修改uac的contact,显然如此

UAC--->第三方Proxy--->OpenSIPS--->FreeSWITCH

参考链接:

https://kb.smartvox.co.uk/opensips/nat-contact-and-via-fixing-in-sip-part-3/

当然,我们可以模仿set_contact_alias函数

route[set_contact_alias] {if (is_present_hf("contact")) {$var(sut) = $si + "~" +  $sp + "~" + $socket_in(proto); # 远端网络地址$var(ct) = $(ct{re.subst,/^(.*)<(.*)>/\2/}); # 取contact <> 里面的内容# 更换成新的contact$var(new_ct) = "<" + $var(ct) + ";my_alias=" + $var(sut) + ">";remove_hf("contact");insert_hf("Contact: $var(new_ct)\r\n", "Call-ID");}
}route[restore_contact_by_alias] {if (!has_totag()) { # 对话内请求才能调用这个路由return;}# xlog("***ru = $ru, du = $du\n");if ($du != NULL) { # 如果已经设置了$du,那么不能再调用这个路由return;}$var(my_alias) = $(ru{nameaddr.param,my_alias});# xlog("***my_alias = $var(my_alias)\n");if ($var(my_alias) != NULL) {$var(ip) = $(var(my_alias){s.select,0,~});$var(port) = $(var(my_alias){s.select,1,~});$var(transport) = $(var(my_alias){s.select,2,~});$var(url) = "sip:" + $var(ip) + ":" + $var(port) + ";transport=" + $var(transport);# xlog("url = $var(url)\n");setdsturi($var(url));$ru  = $(ru{re.subst,/^(sip:.*);my_alias=.*/\1/}); # 删除ru里面的my_alias以及内容		}
}

完整的路由脚本如下:

####### Global Parameters #########/* uncomment the following lines to enable debugging */
#debug_mode=yeslog_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0udp_workers=4/* uncomment the next line to enable the auto temporary blacklisting ofnot available destinations (default disabled) */
#disable_dns_blacklist=no/* uncomment the next line to enable IPv6 lookup after IPv4 dnslookup failures (default disabled) */
#dns_try_ipv6=yessocket=udp:172.20.10.6:5060   # CUSTOMIZE ME
socket=tcp:172.20.10.6:5060   # CUSTOMIZE ME####### Modules Section #########set module path
mpath="/usr/lib/x86_64-linux-gnu/opensips/modules/"#### SIGNALING module
loadmodule "signaling.so"#### StateLess module
loadmodule "sl.so"#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)#### MAX ForWarD module
loadmodule "maxfwd.so"#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)#### MYSQL module
loadmodule "db_mysql.so"#### HTTPD module
loadmodule "httpd.so"
modparam("httpd", "port", 8888)#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-sql-write-back")
modparam("usrloc", "db_url","mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.if you enable this parameter, be sure to enable "append_fromtag"in "rr" module */
modparam("acc", "detect_direction", 0)####  NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG")
modparam("nathelper", "sipping_from", "sip:pinger@127.0.0.1") #CUSTOMIZE ME
modparam("nathelper", "received_avp", "$avp(received_nh)")# loadmodule "rtpproxy.so"
# modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:12221") # CUSTOMIZE ME####  MI_HTTP module
loadmodule "mi_http.so"loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"
####### Routing Logic ######### main request routing logicroute{xlog("$rm|$fU|$tU|$ci from $si:$sp\n");# initial NAT handling; detect if the request comes from behind a NAT# and apply contact fixingforce_rport();#if (nat_uac_test(23)) {if (true) {if (is_method("REGISTER")) {fix_nated_register();setbflag("NAT");} else {# fix_nated_contact();route(set_contact_alias);setflag("NAT");}}if (!mf_process_maxfwd_header(10)) {send_reply(483,"Too Many Hops");exit;}if (has_totag()) {# handle hop-by-hop ACK (no routing required)if ( is_method("ACK") && t_check_trans() ) {t_relay();exit;}# sequential request within a dialog should# take the path determined by record-routingif ( !loose_route() ) {# we do record-routing for all our traffic, so we should not# receive any sequential requests without Route hdr.send_reply(404,"Not here");exit;}route(restore_contact_by_alias);if (is_method("BYE")) {# do accounting even if the transaction failsdo_accounting("log","failed");}if (check_route_param("nat=yes"))setflag("NAT");# route it out to whatever destination was set by loose_route()# in $du (destination URI).route(relay);exit;}# CANCEL processingif (is_method("CANCEL")) {if (t_check_trans())t_relay();exit;}# absorb retransmissions, but do not create transactiont_check_trans();if ( !(is_method("REGISTER")  ) ) {if (is_myself("$fd")) {} else {# if caller is not local, then called number must be localif (!is_myself("$rd")) {send_reply(403,"Relay Forbidden");exit;}}}# preloaded route checkingif (loose_route()) {xlog("L_ERR","Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");if (!is_method("ACK"))send_reply(403,"Preload Route denied");exit;}# record routingif (!is_method("REGISTER|MESSAGE"))record_route();# account only INVITEsif (is_method("INVITE")) {do_accounting("log");}if (!is_myself("$rd")) {append_hf("P-hint: outbound\r\n");route(relay);}# requests for my domainif (is_method("PUBLISH|SUBSCRIBE")) {send_reply(503, "Service Unavailable");exit;}if (is_method("REGISTER")) {if ($socket_in(proto) == "tcp")setflag("TCP_PERSISTENT");if (isflagset("NAT")) {setbflag("SIP_PING_FLAG");}# store the registration and generate a SIP replyif (!save("location"))xlog("failed to register AoR $tu\n");exit;}if ($rU==NULL) {# request with no Username in RURIsend_reply(484,"Address Incomplete");exit;}# do lookup with method filteringif (!lookup("location", "method-filtering")) {t_reply(404, "Not Found");exit;}if (isbflagset("NAT")) setflag("NAT");# when routing via usrloc, log the missed calls alsodo_accounting("log","missed");route(relay);
}route[relay] {# for INVITEs enable some additional helper routesif (is_method("INVITE")) {# if (isflagset("NAT") && has_body("application/sdp")) {#	rtpproxy_offer("ro");# }t_on_branch("per_branch_ops");t_on_reply("handle_nat");t_on_failure("missed_call");}if (isflagset("NAT")) {add_rr_param(";nat=yes");}if (!t_relay()) {send_reply(500,"Internal Error");}exit;
}branch_route[per_branch_ops] {xlog("new branch at $ru\n");
}onreply_route[handle_nat] {#if (nat_uac_test(1))#	fix_nated_contact();route(set_contact_alias);# if ( isflagset("NAT") && has_body("application/sdp") )#	rtpproxy_answer("ro");xlog("incoming reply\n");
}failure_route[missed_call] {if (t_was_cancelled()) {exit;}# uncomment the following lines if you want to block client# redirect based on 3xx replies.##if (t_check_status("3[0-9][0-9]")) {##t_reply(404,"Not found");##	exit;##}
}route[set_contact_alias] {if (is_present_hf("contact")) {$var(sut) = $si + "~" +  $sp + "~" + $socket_in(proto); # 远端网络地址$var(ct) = $(ct{re.subst,/^(.*)<(.*)>/\2/}); # 取contact <> 里面的内容# 更换成新的contact$var(new_ct) = "<" + $var(ct) + ";my_alias=" + $var(sut) + ">";remove_hf("contact");insert_hf("Contact: $var(new_ct)\r\n", "Call-ID");}
}route[restore_contact_by_alias] {if (!has_totag()) { # 对话内请求才能调用这个路由return;}# xlog("***ru = $ru, du = $du\n");if ($du != NULL) { # 如果已经设置了$du,那么不能再调用这个路由return;}$var(my_alias) = $(ru{nameaddr.param,my_alias});# xlog("***my_alias = $var(my_alias)\n");if ($var(my_alias) != NULL) {$var(ip) = $(var(my_alias){s.select,0,~});$var(port) = $(var(my_alias){s.select,1,~});$var(transport) = $(var(my_alias){s.select,2,~});$var(url) = "sip:" + $var(ip) + ":" + $var(port) + ";transport=" + $var(transport);# xlog("url = $var(url)\n");setdsturi($var(url));$ru  = $(ru{re.subst,/^(sip:.*);my_alias=.*/\1/}); # 删除ru里面的my_alias以及内容		}
}

以上脚本在OpenSIPS3.4.3上调试通过,但没测试其他版本

于2024年2月8日(次日即除夕)

全文完

相关文章:

比较Kamailio和OpenSIPS的重写contact函数

Kamailio&#xff1a;调用set_contact_alias()之后&#xff0c;在原有的contact的后面增加参数&#xff0c;具体地说&#xff0c;就是网络地址&#xff0c;网络端口和transport&#xff0c;好处是收到后续请求之时可以恢复原有contact的内容&#xff08;当然也有坏处&#xff0…...

【ETOJ P1046】斐波那契数列 题解(数学+动态规划)

题目描述 给定一个整数 T T T&#xff0c;表示样例数。 对于每个样例&#xff0c;给定一个整数 n n n&#xff0c;求斐波那契数列的第 n n n 项。 斐波那契数列定义为 f ( 1 ) f ( 2 ) 1 f(1) f(2) 1 f(1)f(2)1&#xff0c; f ( n ) f ( n − 1 ) f ( n − 2 ) f(…...

编码技巧——基于RedisTemplate的RedisClient实现、操作Lua脚本

1. 背景 在新公司的脚手架中开发&#xff0c;需要用到redis&#xff0c;发现没有封装好一套能集成各种常用命令、包括Lua脚本的方便使用的RedisTemplateClient&#xff0c;于是自己来实现下&#xff1b; springboot整合redis之后&#xff0c;提供了操作redis的简便方式&#…...

Asp .Net Core 系列:Asp .Net Core 集成 Panda.DynamicWebApi

文章目录 简介Asp .Net Core 集成 Panda.DynamicWebApi配置原理什么是POCO Controller&#xff1f;POCO控制器原理ControllerFeatureProvider实现自定义判断规则IApplicationModelConventionPanda.DynamicWebApi中的实现ConfigureApiExplorer()ConfigureSelector()ConfigurePar…...

【PTA浙大版《C语言程序设计(第4版)》|编程题】习题7-3 判断上三角矩阵(附测试点)

目录 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 代码呈现 测试点 上三角矩阵指主对角线以下的元素都为0的矩阵&#xff1b;主对角线为从矩阵的左上角至右下角的连线。 本题要求编写程序&#xff0c;判断一个给定的方阵是否…...

JVM 性能调优 - 参数调优(3)

查看 JVM 内存的占用情况 编写代码 package com.test;public class PrintMemoryDemo {public static void main(String[] args) {// 堆内存总量long totalMemory Runtime.getRuntime().totalMemory();// jvm 试图使用的最大堆内存long maxMemory Runtime.getRuntime().maxM…...

Django(十)

1. Ajax请求 浏览器向网站发送请求时&#xff1a;URL 和 表单的形式提交。 GETPOST 特点&#xff1a;页面刷新。 除此之外&#xff0c;也可以基于Ajax向后台发送请求&#xff08;偷偷的发送请求&#xff09;。 依赖jQuery编写ajax代码 $.ajax({url:"发送的地址"…...

OpenHarmony开源鸿蒙开发之旅

文章目录 一、op系统架构二、op系统构建1. op源代码目录2. op系统构建3. op开发环境搭建 三、op系统的子系统四、op系统芯片移植五、op系统启动流程六、op系统组件七、驱动框架 一、op系统架构 二、op系统构建 1. op源代码目录 2. op系统构建 3. op开发环境搭建 三、op系统…...

SpringBoot之整合PageHelper分页插件

SpringBoot之整合PageHelper分页插件 文章目录 SpringBoot之整合PageHelper分页插件1. 引入坐标2. application.yml配置3. 基本使用4. 对多个查询执行分页1. 默认第一个Select语句会执行分页2. 让Pagehelper也能执行多个分页的方法3. 完整案例 详细配置请查看官网或MyBatis分页…...

Android java基础_类的封装

一.面向对象编程的引入 写一个简单的程序输出张三&#xff0c;李四的名字 class Person {String name;String getName() {return "guangdong "name;} };public class Oop {public static void main(String args[]) {Person p1 new Person();p1.name "zhangs…...

Vue-57、Vue技术路由的参数如何传递

query参数传递 1、传递参数 <!-- 跳转路由并携带query参数&#xff0c;to的字符串写法--> <router-link :to"/home/message/detail?id${p.id}&title${p.title}"> {{p.title}} </router-link><!-- 跳转路由…...

《MySQL 简易速速上手小册》第1章:MySQL 基础和安装(2024 最新版)

文章目录 1.1 MySQL 概览&#xff1a;版本、特性和生态系统1.1.1 基础知识1.1.2 重点案例&#xff1a;使用 Python 实现 MySQL 数据的 CRUD 操作1.1.3 拓展案例 1&#xff1a;使用 Python 实现 MySQL 数据备份**1.1.4 拓展案例 2&#xff1a;使用 Python 分析 MySQL 数据 1.2 安…...

Linux 软件管理(YUM RPM)

1 YUM yum&#xff08;全称为 Yellow dog Updater, Modified&#xff09;是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的服务器自动处理依赖性关系&#xff0c;并且一次安装所有依赖的软件包&#xff0c;无须繁琐地一次次…...

【Makefile语法 05】动静态库编译链接

目录 一、多文件项目源代码 二、静态库编译链接 三、动态库编译链接 一、多文件项目源代码 // include/add.hpp#pragma once int add(int a, int b); // include/sub.hpp#pragma once int sub(int a, int b); // src/add.cpp#include "add.hpp"int add(int a, …...

JS - 处理元素滚动

业务功能中时常有元素滚动的功能&#xff0c;现在就总结一下一些常用的事件。 一、定位滚动元素 做一切滚动操作之前都应该先定位到滚动元素&#xff0c;再做其他操作&#xff0c;如滚动顶部&#xff0c;获取滚动距离、禁止滚动等。 把以下代码复制粘贴到浏览器 Console 面板…...

JavaScript滚动事件

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 滚动是网页交互不可或缺的一部分。监听页面和元素的滚动事件,可以帮助…...

4.0 Zookeeper Java 客户端搭建

本教程使用的 IDE 为 IntelliJ IDEA&#xff0c;创建一个 maven 工程&#xff0c;命名为 zookeeper-demo&#xff0c;并且引入如下依赖&#xff0c;可以自行在maven中央仓库选择合适的版本&#xff0c;介绍原生 API 和 Curator 两种方式。 IntelliJ IDEA 相关介绍&#xff1a;…...

C#既然数组长度不可改变,那么如何动态调整集合类型数组大小,以便添加或删除元素?

目录 1.使用动态数组&#xff08;ArrayList&#xff09;&#xff1a; 2.使用 jagged array&#xff08;不规则数组&#xff09;&#xff1a; 3.使用 List &#xff1a; 4.使用数组复制&#xff1a; 在C#中&#xff0c;数组的长度是固定的&#xff0c;一旦声明和初始化&…...

3.1 Verilog 连续赋值

关键词&#xff1a;assign&#xff0c; 全加器 连续赋值语句是 Verilog 数据流建模的基本语句&#xff0c;用于对 wire 型变量进行赋值。&#xff1a; 格式如下 assign LHS_target RHS_expression &#xff1b; LHS&#xff08;left hand side&#xff09; 指赋值操作…...

【http】2、http request header Origin 属性、跨域 CORS、同源、nginx 反向代理、预检请求

文章目录 一、Origin 含义二、跨源资源共享&#xff1a;**Cross-Origin Resource Sharing** CORS2.1 跨域的定义2.2 功能概述2.3 场景示例2.3.1 简单请求2.3.2 Preflighted requests&#xff1a;预检请求 2.4 header2.4.1 http request header2.4.1.1 Origin2.4.1.2 Access-Con…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...