Oghje, ci sò suluzioni pronti (proprietarii) per surviglià i flussi IP (TS), per esempiu
Moltu brevemente nantu à TSduck
TSDuck hè un software open source (licenza BSD 2-Clause) (un inseme di utilità di cunsola è una biblioteca per sviluppà utilità o plugins persunalizati) per manipulà i flussi TS. Cum'è un input, pò travaglià cù IP (multicast/unicast), http, hls, dvb tuners, dektec dvb-asi demodulator, ci hè un generatore TS-stream internu è leghje da i schedari. L'output pò esse scrittu à un schedariu, IP (multicast/unicast), hls, dektec dvb-asi è modulatori HiDes, players (mplayer, vlc, xine) è drop. Diversi processori di trafficu ponu esse inclusi trà l'input è l'output, per esempiu, remapping PID, scrambling / descrambling, analisi di contatore CC, calculu di bitrate, è altre operazioni tipiche per i flussi TS.
In questu articulu, i flussi IP (multicast) seranu utilizati com'è input, i prucessori bitrate_monitor (da u nome hè chjaru ciò chì hè) è a continuità (analisi di i contatori CC) sò usati. Pudete facilmente rimpiazzà IP multicast cù un altru tipu di input supportatu da TSduck.
Disponibile
In seguitu, a versione TSDuck 3.19-1520 hè aduprata, Linux hè utilizatu cum'è OS (debian 10 hè stata utilizata per preparà a suluzione, CentOS 7 hè stata utilizata per un usu veru)
Preparazione di TSduck è OS
Prima di monitorà i flussi reali, avete bisognu di assicurà chì TSDuck funziona bè è ùn ci sò micca gocce à u livellu di a carta di rete o di u SO (socket). Questu hè necessariu per ùn guessà più tardi induve e gocce sò accadute - in a reta o "dentro u servitore". Pudete cuntrollà i gocce à u nivellu di a carta di rete cù u cumandimu ethtool -S ethX, a sintonizazione hè fatta da u listessu ethtool (di solitu, avete bisognu di aumentà u buffer RX (-G) è qualchì volta disattiveghjanu qualchi offloads (-K)). Cum'è una ricunniscenza generale, pò esse cunsigliatu di utilizà un portu separatu per riceve u trafficu analizatu, se pussibule, questu minimize falsi pusitivi assuciati cù u fattu chì a goccia hè accaduta esattamente nantu à u portu di l'analizzatore per a presenza di un altru trafficu. Se questu ùn hè micca pussibule (un mini-computer / NUC cù un portu hè utilizatu), allora hè assai desideratu di stabilisce a priorità di u trafficu analizatu in relazione à u restu nantu à u dispusitivu à quale l'analizzatore hè cunnessu. In quantu à l'ambienti virtuali, quì ci vole à esse attentu è esse capace di truvà gocce di pacchetti partendu da un portu fisicu è finiscinu cù una applicazione in una macchina virtuale.
Generazione è ricezione di un flussu in l'ospite
Cum'è un primu passu in a preparazione di TSduck, genereremu è riceverà trafficu in un unicu host utilizendu netns.
Preparazione di l'ambiente:
ip netns add P #создаём netns P, в нём будет происходить анализ трафика
ip link add type veth #создаём veth-пару - veth0 оставляем в netns по умолчанию (в этот интерфейс будет генерироваться трафик)
ip link set dev veth1 netns P #veth1 - помещаем в netns P (на этом интерфейсе будет приём трафика)
ip netns exec P ifconfig veth1 192.0.2.1/30 up #поднимаем IP на veth1, не имеет значения какой именно
ip netns exec P ip ro add default via 192.0.2.2 #настраиваем маршрут по умолчанию внутри nents P
sysctl net.ipv6.conf.veth0.disable_ipv6=1 #отключаем IPv6 на veth0 - это делается для того, чтобы в счётчик TX не попадал посторонний мусор
ifconfig veth0 up #поднимаем интерфейс veth0
ip route add 239.0.0.1 dev veth0 #создаём маршрут, чтобы ОС направляла трафик к 239.0.0.1 в сторону veth0
L'ambiente hè prontu. Cuminciamu l'analizzatore di trafficu:
ip netns exec P tsp --realtime -t
-I ip 239.0.0.1:1234
-P continuity
-P bitrate_monitor -p 1 -t 1
-O drop
induve "-p 1 -t 1" significa chì avete bisognu di calculà u bitrate ogni secondu è visualizà infurmazioni nantu à u bitrate ogni secondu
Cuminciamu u generatore di trafficu cù una velocità di 10 Mbps:
tsp -I craft
-P regulate -b 10000000
-O ip -p 7 -e --local-port 6000 239.0.0.1:1234
induve "-p 7 -e" significa chì avete bisognu di imballà 7 pacchetti TS in 1 pacchettu IP è fate dura (-e), i.e. aspetta sempre 7 pacchetti TS da l'ultimu processatore prima di mandà un pacchettu IP.
L'analizzatore cumencia à emette i missaghji previsti:
* 2020/01/03 14:55:44 - bitrate_monitor: 2020/01/03 14:55:44, TS bitrate: 9,970,016 bits/s
* 2020/01/03 14:55:45 - bitrate_monitor: 2020/01/03 14:55:45, TS bitrate: 10,022,656 bits/s
* 2020/01/03 14:55:46 - bitrate_monitor: 2020/01/03 14:55:46, TS bitrate: 9,980,544 bits/s
Avà aghjunghje alcune gocce:
ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP
è missaghji cum'è questu appariscenu:
* 2020/01/03 14:57:11 - continuity: packet index: 80,745, PID: 0x0000, missing 7 packets
* 2020/01/03 14:57:11 - continuity: packet index: 83,342, PID: 0x0000, missing 7 packets
chì hè aspittatu. Disattivate a perdita di pacchetti (ip netns exec P iptables -F) è pruvate d'aumentà u bitrate di u generatore à 100 Mbps. L'analizzatore informa una mansa di errori CC è circa 75 Mbps invece di 100. Avemu pruvatu à capisce quale hè a culpa - u generatore ùn hà micca tempu o u prublema ùn hè micca in questu, per questu avemu principiatu à generà un numeru fissu di pacchetti (700000 pacchetti TS = 100000 pacchetti IP):
# ifconfig veth0 | grep TX
TX packets 151825460 bytes 205725459268 (191.5 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# tsp -I craft -c 700000 -P regulate -b 100000000 -P count -O ip -p 7 -e --local-port 6000 239.0.0.1:1234
* count: PID 0 (0x0000): 700,000 packets
# ifconfig veth0 | grep TX
TX packets 151925460 bytes 205861259268 (191.7 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Comu pudete vede, esattamente 100000 pacchetti IP sò stati generati (151925460-151825460). Allora scopremu ciò chì succede cù l'analizzatore, per questu cuntrollemu cù u contatore RX in veth1, hè strettamente uguale à u contatore TX in veth0, allora guardemu ciò chì succede à u nivellu di socket:
# ip netns exec P cat /proc/net/udp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
133: 010000EF:04D2 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 72338 2 00000000e0a441df 24355
Quì pudete vede u numeru di gocce = 24355. In i pacchetti TS, questu hè 170485 o 24.36% di 700000, cusì vedemu chì quelli stessi 25% di u bitrate persu sò gocce in u socket udp. Gocce in un socket UDP sò generalmente per una mancanza di buffer, fighjate à a dimensione di buffer di socket predeterminata è a dimensione massima di buffer di socket:
# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992
Cusì, se l'applicazioni ùn dumandanu micca esplicitamente una dimensione di buffer, i sockets sò creati cù un buffer di 208 KB, ma se dumandanu più, ùn riceveranu micca ciò chì era dumandatu. Siccomu pudete stabilisce a dimensione di u buffer in tsp per l'input IP (-buffer-size), ùn avemu micca toccu a dimensione di u socket predeterminatu, ma solu stabilisce a dimensione massima di u buffer di u socket è specificà a dimensione di u buffer esplicitamente attraversu l'argumenti tsp:
sysctl net.core.rmem_max=8388608
ip netns exec P tsp --realtime -t -I ip 239.0.0.1:1234 -b 8388608 -P continuity -P bitrate_monitor -p 1 -t 1 -O drop
Cù sta sintonizazione di u buffer di socket, avà u bitrate rappurtatu hè di circa 100Mbps, ùn ci sò micca errori CC.
Sicondu u cunsumu CPU di l'applicazione tsp stessu. Relativamente à un core i5-4260U CPU @ 1.40GHz, l'analisi di flussu 10Mbps necessitarà 3-4% CPU, 100Mbps - 25%, 200Mbps - 46%. Quandu stabilisce u % Packet Loss, a carica nantu à u CPU praticamente ùn aumenta (ma pò diminuite).
Nantu à un hardware più produtivu, era pussibule generà è analizà flussi di più di 1 Gb / s senza prublemi.
Pruvate nantu à e carte di rete reale
Dopu à pruvà à un paru veth, vi tocca à piglià dui ospiti o dui porti di un òspite, cunnette i porti à l'altri, principià u generatore nantu à unu, è l'analizzatore nantu à u sicondu. Ùn ci era micca sorprese quì, ma in fatti tuttu dipende di u ferru, u più debule, u più interessante serà quì.
Utilizà i dati ricevuti da u sistema di monitoraghju (Zabbix)
tsp ùn hà micca alcuna API leggibile da a macchina cum'è SNMP o simili. I missaghji CC devenu esse aggregati per almenu 1 segundu (cù un altu percentualità di perdita di pacchetti, pò esse centinaie / millaie / decine di millai per seconda, secondu u bitrate).
Cusì, per salvà l'infurmazioni è disegnà grafici per errori CC è bitrate è fà qualchì tipu d'accidenti, ponu esse l'opzioni seguenti:
- Parse è aggregate (da CC) l'output di tsp, i.e. cunvertisce à a forma desiderata.
- Finisci tsp stessu è / o plugins di prucessori bitrate_monitor è continuità per chì u risultatu hè datu in una forma leggibile in macchina adattata per u sistema di surviglianza.
- Scrivite a vostra applicazione nantu à a biblioteca tsduck.
Ovviamente, l'opzione 1 hè a più faciule in termini di sforzu, soprattuttu cunsiderendu chì tsduck stessu hè scrittu in una lingua di livellu bassu (da i standard muderni) (C ++)
Un prototipu bash parser + aggregator simplice hà dimustratu chì in un flussu di 10Mbps è 50% di perdita di pacchetti (u peghju casu), u prucessu bash hà cunsumatu 3-4 volte più CPU cà u prucessu tsp stessu. Stu scenariu hè inacceptable. In realtà un pezzu di stu prototipu quì sottu
Noodles nantu à a cima
#!/usr/bin/env bash
missingPackets=0
ccErrorSeconds=0
regexMissPackets='^* (.+) - continuity:.*missing ([0-9]+) packets$'
missingPacketsTime=""
ip netns exec P tsp --realtime -t -I ip -b 8388608 "239.0.0.1:1234" -O drop -P bitrate_monitor -p 1 -t 1 -P continuity 2>&1 |
while read i
do
#line example:* 2019/12/28 23:41:14 - continuity: packet index: 6,078, PID: 0x0100, missing 5 packets
#line example 2: * 2019/12/28 23:55:11 - bitrate_monitor: 2019/12/28 23:55:11, TS bitrate: 4,272,864 bits/s
if [[ "$i" == *continuity:* ]]
then
if [[ "$i" =~ $regexMissPackets ]]
then
missingPacketsTimeNew="${BASH_REMATCH[1]}" #timestamp (seconds)
if [[ "$missingPacketsTime" != "$missingPacketsTimeNew" ]] #new second with CC error
then
((ccErrorSeconds += 1))
fi
missingPacketsTime=$missingPacketsTimeNew
packets=${BASH_REMATCH[2]} #TS missing packets
((missingPackets += packets))
fi
elif [[ "$i" == *bitrate_monitor:* ]]
then
: #...
fi
done
In più di esse inaccettabilmente lentu, ùn ci sò micca fili nurmali in bash, i travaglii di bash sò prucessi separati è aghju avutu à scrive u valore di missingPackets una volta à seconda nantu à l'effettu side (quandu riceve missaghji di bitrate chì venenu ogni secondu). In u risultatu, bash hè stata lasciata sola è hè statu decisu di scrive un wrapper (parser + aggregator) in golang. U cunsumu di CPU di codice golang simili hè 4-5 volte menu di u prucessu tsp stessu. L'accelerazione di u wrapper per via di a sustituzione di bash cù golang hè stata circa 16 volte è in generale u risultatu hè accettabile (CPU overhead da 25% in u peghju casu). U schedariu fonte golang hè situatu
Run wrapper
Per inizià u wrapper, u mudellu di serviziu più simplice per systemd hè statu fattu (
Per creà una istanza di u serviziu, avete bisognu di eseguisce u cumandimu systemctl enable [email prutettu]: 1234 poi eseguite cù systemctl start [email prutettu]: 1234.
Scoperta da Zabbix
Per fà chì zabbix possa scopre i servizii in esecuzione, hè fattu
U mudellu Zabbix
Breve lista di cuntrollu (bene, chì se qualchissia decide di usà)
- Assicuratevi chì tsp ùn sguassate micca pacchetti in cundizioni "ideali" (generatore è analizatore sò cunnessi direttamente), se ci sò gocce, vede u paràgrafu 2 o u testu di l'articulu nantu à sta materia.
- Fate tuning u buffer di socket massimu (net.core.rmem_max=8388608).
- Cumpilà tsduck-stat.go (andà à custruisce tsduck-stat.go).
- Mettite u mudellu di serviziu in /lib/systemd/system.
- Cumincià i servizii cù systemctl, verificate chì i cuntatori anu cuminciatu à apparisce (grep "" /dev/shm/tsduck-stat/*). U numeru di servizii da u numeru di flussi multicast. Quì pudete bisognu di creà una strada à u gruppu multicast, forsi disattivà rp_filter o crea una strada à l'ip di fonte.
- Eseguite discovery.sh, assicuratevi chì genera json.
- Aghjunghjite a cunfigurazione di l'agente zabbix, riavvia l'agente zabbix.
- Caricate u mudellu à zabbix, appricà à l'ospite chì hè monitoratu è u zabbix-agent hè stallatu, aspettate circa 5 minuti, vede s'ellu ci sò novi elementi, grafici è triggers.
risultatu
Per u compitu di detectà a perdita di pacchettu, hè quasi abbastanza, almenu hè megliu cà senza surviglianza.
Infatti, "perdite" di CC pò accade quandu si fusione frammenti di video (finu à ciò chì sò, hè cusì chì l'inserzioni sò fatti in i centri TV lucali in a Federazione Russa, vale à dì senza ricalculare u cuntatore CC), questu deve esse ricurdatu. Soluzioni prupietarie parzialmente circundanu stu prublema detectendu etichette SCTE-35 (se aghjunte da u generatore di flussu).
In quantu à u monitoraghju di a qualità di trasportu, ci hè una mancanza di monitorizazione di jitter (IAT). L'equipaggiu di TV (sia modulatori o dispositi finali) hà esigenze per questu paràmetru è ùn hè micca sempre pussibule di gonfià u jitbuffer à l'infinitu. È u jitter pò flutterà quandu l'equipaggiu cù grande buffer hè utilizatu in transitu è QoS ùn hè micca cunfiguratu o micca bè cunfiguratu abbastanza per trasmette stu trafficu in tempu reale.
Source: www.habr.com