From 91716e523325333ea917e075715ffedbab8481de Mon Sep 17 00:00:00 2001 From: sorcier Date: Tue, 10 Nov 2026 11:16:29 +0100 Subject: [PATCH] release(v1.6.6): apply PJSIP RTP timeouts, SIP timers and TLS/NAT keepalives for off-network phones --- src/ConfigGenerator.php | 32 ++++++++++++++++++++++++++++++++ version.json | 6 ++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/ConfigGenerator.php b/src/ConfigGenerator.php index b895584..e37eedf 100644 --- a/src/ConfigGenerator.php +++ b/src/ConfigGenerator.php @@ -67,6 +67,25 @@ class ConfigGenerator $lines[] = "; ==========================================================================="; $lines[] = ""; + $rtpTimeout = max(5, (int)($settings['rtp_timeout'] ?? 30)); + $rtpHoldTimeout = max(0, (int)($settings['rtp_timeout_hold'] ?? 0)); + $rtpKeepalive = max(0, (int)($settings['rtp_keepalive'] ?? 15)); + + $tcpKeepaliveLines = [ + "tcp_keepalive_enable = yes", + "tcp_keepalive_idle_time = 20", + "tcp_keepalive_interval_time = 5", + "tcp_keepalive_probe_count = 3", + ]; + + // 0. Paramètres globaux PJSIP (Keepalive applicatif TLS/TCP toutes les 30s pour postes hors réseau / NAT) + $lines[] = "; --- PARAMÈTRES GLOBAUX PJSIP (KEEPALIVE NAT / HORS RÉSEAU) ---"; + $lines[] = "[global]"; + $lines[] = "type = global"; + $lines[] = "keep_alive_interval = 30"; + $lines[] = "contact_expiration_check_interval = 15"; + $lines[] = ""; + // 1. Transport UDP (Postes internes LAN & Trunks standards) $lines[] = "; --- TRANSPORT UDP (LAN / INTERNE) ---"; $lines[] = "[transport-udp]"; @@ -110,6 +129,7 @@ class ConfigGenerator $lines[] = "external_signaling_port = {$extUdpPort}"; } } + array_push($lines, ...$tcpKeepaliveLines); $lines[] = "allow_reload = no"; $lines[] = ""; @@ -180,6 +200,7 @@ class ConfigGenerator $lines[] = "external_signaling_port = {$extTlsPort}"; } } + array_push($lines, ...$tcpKeepaliveLines); $lines[] = "allow_reload = no"; $lines[] = ""; @@ -221,6 +242,15 @@ class ConfigGenerator $lines[] = "force_rport = yes"; $lines[] = "rewrite_contact = yes"; $lines[] = "direct_media = no"; + // Détection automatique et purge des flux RTP fantômes / morts (coupure réseau, NAT hors réseau) + $lines[] = "rtp_timeout = {$rtpTimeout}"; + $lines[] = "rtp_timeout_hold = {$rtpHoldTimeout}"; + if ($rtpKeepalive > 0) { + $lines[] = "rtp_keepalive = {$rtpKeepalive}"; + } + $lines[] = "timers = yes"; + $lines[] = "timers_min_se = 90"; + $lines[] = "timers_sess_expires = 1800"; if ($wantsTls && $hasTlsCerts) { // Verrouillage strict du transport TLS : refuse le repli sur UDP $lines[] = "transport = transport-tls"; @@ -374,6 +404,8 @@ class ConfigGenerator $lines[] = "trust_id_inbound = {$trustInbound}"; $lines[] = "trust_id_outbound = {$trustOutbound}"; $lines[] = "timers = {$timers}"; + $lines[] = "rtp_timeout = {$rtpTimeout}"; + $lines[] = "rtp_timeout_hold = {$rtpHoldTimeout}"; if ($rtpKeepalive > 0) { $lines[] = "rtp_keepalive = {$rtpKeepalive}"; } diff --git a/version.json b/version.json index 03e0047..e4c8f1b 100644 --- a/version.json +++ b/version.json @@ -1,9 +1,11 @@ { - "version": "1.6.5", + "version": "1.6.6", "codename": "Helios", - "release_date": "2026-11-05", + "release_date": "2026-11-10", "min_php_version": "8.2", "changelog": [ + "PJSIP Endpoints & Trunks : injection effective de rtp_timeout, rtp_timeout_hold, rtp_keepalive et SIP Session Timers (RFC 4028) sur chaque endpoint PJSIP pour raccrocher instantanément les canaux fantômes", + "PJSIP Global & Transports TLS/TCP : keepalive applicatif réduit à 30s (keep_alive_interval = 30), vérification expiration contacts toutes les 15s et TCP keepalives noyau (20s/5s/3) pour fiabiliser les BLF et postes hors réseau derrière NAT", "Trunks SIP : dissociation stricte du CallerID sortant du Trunk (suppression de callerid dans l'endpoint PJSIP pour préserver l'affichage du numéro appelant réel sur les appels entrants)", "Trunks SIP : suppression du forçage de from_user afin de préserver l'en-tête SIP From dynamique avec Nom d'appelant (CNAM) pour OVH / Orange", "Trunks SIP & Routage Sortant : activation systématique de trust_id_outbound et formatage strict du Caller ID Name (CNAM) pour affichage garanti chez les opérateurs distants (OVH, Orange, etc.)",