TSduck erabiliz IP(TS) korronteak monitorizatzeko

Gaur egun, IP(TS) korronteak monitorizatzeko prest dauden irtenbideak (jabeak) daude, adibidez VB ΠΈ iQ, funtzio multzo nahiko aberatsa dute eta normalean telebista zerbitzuekin aritzen diren operadore handiek horrelako irtenbideak dituzte. Artikulu honek kode irekiko proiektu batean oinarritutako irtenbide bat deskribatzen du TSDuck, IP(TS) korronteen kontrol minimorako diseinatua CC (jarraitutasun-kontagailua) kontagailuaren eta bit-abiaduraren bidez. Aplikazio posible bat paketeen galera edo fluxu osoa alokatuta dagoen L2 kanal baten bidez kontrolatzea da (normalean kontrolatu ezin dena, adibidez, ilaretan galera-kontagailuak irakurriz).

Oso labur TSduck-i buruz

TSduck kode irekiko (2 klausula BSD lizentzia) software bat da (kontsolaren utilitateen multzoa eta liburutegia utilitate edo plugin pertsonalizatuak garatzeko) TS korronteak manipulatzeko. Sarrera gisa, IP (multicast/unicast), http, hls, dvb sintonizatzaileak, dektec dvb-asi demoduladorearekin lan egin dezake, barneko TS-stream sorgailu bat dago eta fitxategietatik irakurtzen da. Irteera fitxategi batean idatzi daiteke, IP (multicast/unicast), hls, dektec dvb-asi eta HiDes modulatzaileak, erreproduzitzaileak (mplayer, vlc, xine) eta drop. Sarreraren eta irteeraren artean hainbat trafiko-prozesadore sar daitezke, adibidez, PID birmapping, nahasketa/descrambling, CC kontagailuaren analisia, bit-tasa kalkulatzea eta TS korronteetarako beste eragiketa tipiko batzuk.

Artikulu honetan, IP korronteak (multicast) erabiliko dira sarrera gisa, prozesadoreak bitrate_monitor (izenetik argi dago zer den) eta jarraitutasuna (CC kontagailuen analisia) erabiltzen dira. IP multicast erraz ordezkatu dezakezu TSduck-ek onartzen duen beste sarrera mota batekin.

Eskuragarri daude eraikuntza/pakete ofizialak TSduck egungo sistema eragile gehienetarako. Ez daude Debian-erako erabilgarri, baina debian 8 eta debian 10-ekin arazorik gabe eraikitzea lortu dugu.

Ondoren, TSduck 3.19-1520 bertsioa erabiltzen da, Linux sistema eragile gisa (debian 10 erabili zen irtenbidea prestatzeko, CentOS 7 erabili zen benetako erabilerarako)

TSduck eta OS prestatzen

Fluxu errealak kontrolatu aurretik, ziurtatu behar duzu TSDuck-ek behar bezala funtzionatzen duela eta sare-txartelean edo OS (socket) mailan ez dagoela tantarik. Hau beharrezkoa da erorketak non gertatu diren gero ez asmatzeko - sarean edo "zerbitzariaren barruan". Sareko txartelaren mailan jaitsierak egiazta ditzakezu ethtool -S ethX komandoarekin, sintonizazioa ethtool berak egiten du (normalean, RX buffera (-G) handitu behar duzu eta batzuetan deskarga batzuk (-K) desgaitu behar dituzu). Gomendio orokor gisa, aztertutako trafikoa jasotzeko ataka bereizi bat erabiltzea gomendatzen da, ahal izanez gero, positibo faltsuak minimizatzen ditu beherakada analizatzailearen atakan gertatu zelako beste trafiko bat egoteagatik. Hau ezinezkoa bada (mini-ordenagailu/NUC ataka bat erabiltzen da), orduan oso komenigarria da aztertutako trafikoaren lehentasuna ezartzea analizatzailea konektatuta dagoen gailuan gainerakoekiko. Ingurune birtualei dagokienez, hemen kontuz ibili behar da eta pakete-tantak aurkitzeko gai izan behar duzu portu fisiko batetik hasi eta makina birtual baten barruan dagoen aplikazio batekin amaituz.

Ostalari barruan korronte bat sortzea eta jasotzea

TSduck prestatzeko lehen urrats gisa, ostalari bakarrean trafikoa sortu eta jasoko dugu netns erabiliz.

Ingurumena prestatzea:

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

Ingurunea prest dago. Trafiko analizatzailea abiarazten dugu:

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

non "-p 1 -t 1" esan nahi du segundoro bit-tasa kalkulatu behar duzula eta segundoro bit-abiadurari buruzko informazioa bistaratu behar duzula
Trafiko-sorgailua 10Mbps-ko abiadurarekin abiarazten dugu:

tsp -I craft 
 -P regulate -b 10000000 
 -O ip -p 7 -e --local-port 6000 239.0.0.1:1234

non "-p 7 -e" esan nahi du 7 TS pakete IP pakete batean ontziratu behar dituzula eta gogor egin (-e), hau da. beti itxaron azken prozesadoretik 1 TS pakete IP pakete bat bidali aurretik.

Analizatzailea espero diren mezuak ateratzen hasten da:

* 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

Orain gehitu tanta batzuk:

ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP

eta honelako mezuak agertzen dira:

* 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 

espero dena. Desgaitu pakete-galera (ip netns exec P iptables -F) eta saiatu sorgailuaren bit-tasa 100Mbps-ra handitzen. Analizatzaileak CC akats mordoa eta 75 Mbps inguru 100en ordez adierazten ditu. Errua nor den asmatzen saiatzen ari gara - sorgailuak ez du denborarik edo arazoa ez dago bertan, horretarako kopuru finko bat sortzen hasten gara. paketeak (700000 TS pakete = 100000 IP pakete):

# 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

Ikus dezakezunez, zehazki 100000 IP pakete sortu ziren (151925460-151825460). Beraz, azter dezagun zer gertatzen ari den analizagailuarekin, horretarako RX kontagailuarekin egiaztatuko dugu veth1-en, TX kontagailuaren berdina da zorrozki veth0-n, gero socket mailan gertatzen dena aztertuko dugu:

# 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 

Hemen jaitsiera kopurua = 24355 ikus dezakezu. TS paketeetan, hau 170485 edo 24.36-ren % 700000 da, beraz, galdutako bit-abiaduraren % 25 horiek udp socket-eko tantak direla ikusten dugu. UDP socket batean erorketak buffer faltagatik gertatzen dira normalean, begiratu socket buffer tamaina lehenetsia eta socket buffer gehienezko tamaina:

# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992

Horrela, aplikazioek ez badute espresuki buffer tamaina eskatzen, socketak 208 KB-ko buffer batekin sortzen dira, baina gehiago eskatzen badute, oraindik ez dute eskatutakoa jasoko. Buffer-en tamaina IP sarrerarako tsp-n ezar dezakezunez (-buffer-size), ez dugu socket-tamaina lehenetsia ukituko, baizik eta socket-en buffer-en gehienezko tamaina ezarriko dugu eta bufferaren tamaina esplizituki zehaztuko dugu tsp argumentuen bidez:

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

Socket buffer-aren sintonizazio honekin, orain jakinarazitako bit-tasa 100Mbps ingurukoa da, ez dago CC akatsik.

Tsp aplikazioaren beraren CPU kontsumoaren arabera. Nukleo i5-4260U CPU @ 1.40GHz, 10Mbps-ko fluxuaren azterketak %3-4ko CPU, 100Mbps -%25, 200Mbps -%46 beharko ditu. % Pakete-galera ezartzean, CPUaren karga ia ez da handitzen (baina txikitu egin daiteke).

Hardware produktiboagoan, 1 Gb / s baino gehiagoko korronteak sortu eta aztertzea posible zen arazorik gabe.

Sare errealeko txarteletan probak

Veth bikote batean probatu ondoren, ostalari baten bi ostalari edo bi ataka hartu behar dituzu, portuak elkarri konektatu, sorgailua batean abiarazi eta analizatzailea bigarrenean. Hemen ez zen ezustekorik izan, baina, egia esan, dena burdinaren araberakoa da, zenbat eta ahulagoa, orduan eta interesgarriagoa izango da hemen.

Jarraipen-sistemak jasotako datuak erabiliz (Zabbix)

tsp-k ez du makinaz irakur daitekeen APIrik, SNMP edo antzeko gisa. CC mezuak gutxienez segundo batean gehitu behar dira (pakete-galera portzentaje handiarekin, ehunka/milaka/hamarka mila izan daitezke segundoko, bit-abiaduraren arabera).

Horrela, bai informazioa gordetzeko bai CC akatsen eta bit-abiaduraren grafikoak marraztu eta nolabaiteko istripuak egiteko, aukera hauek egon daitezke:

  1. Analizatu eta batu (CC bidez) tsp-en irteera, hau da. bihurtu nahi duzun formara.
  2. Amaitu tsp bera eta/edo prozesadorearen pluginak bitrate_monitor eta jarraitutasuna, emaitza monitorizazio sistemarako egokia den makinaz irakur daitekeen moduan eman dadin.
  3. Idatzi zure eskaera tsduck liburutegiaren gainean.

Jakina, 1. aukera errazena da esfortzuari dagokionez, batez ere kontuan hartuta tsduck bera maila baxuko (estandar modernoen arabera) hizkuntza batean (C ++) idatzita dagoela.

Bash analizatzaile+agregatzaile prototipo sinple batek erakutsi zuen 10Mbps-ko korronte batean eta %50eko pakete galeran (kasurik txarrena), bash-prozesuak tsp prozesuak berak baino 3-4 aldiz CPU gehiago kontsumitzen zuela. Eszenatoki hau onartezina da. Egia esan, beheko prototipo honen zati bat

Fideoak goian

#!/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

Onartezina den motela izateaz gain, bash-en ez dago hari normalik, bash-lanak prozesu bereiziak dira eta missingPackets-en balioa segunduan behin idatzi behar izan nuen albo-efektuan (segundoro etortzen diren bit-tasa mezuak jasotzean). Ondorioz, bash bakarrik geratu zen eta bilgarri bat (analizatzailea + agregatzailea) golang-en idaztea erabaki zen. Golang kodearen antzeko CPUaren kontsumoa tsp prozesua bera baino 4-5 aldiz txikiagoa da. Bash-a golang-arekin ordezkatzearen ondorioz bilgarriaren bizkortzea 16 aldiz inguru izan zen eta, oro har, emaitza onargarria da (kasu txarrenean CPUaren gainkostua % 25). Golang iturburu-fitxategia dago Hemen.

Exekutatu bilgarria

Wrapper-a abiarazteko, systemd-rako zerbitzu-txantiloirik errazena egin zen (Hemen). Bilgarria bera /opt/tsduck-stat/-en dagoen fitxategi bitar batean (joan build tsduck-stat.go) konpilatu behar da. Suposatzen da golang erabiltzen ari zarela erloju monotonikoaren laguntzarekin (>=1.9).

Zerbitzuaren instantzia bat sortzeko, systemctl enable komandoa exekutatu behar duzu [posta elektroniko bidez babestua]:1234 ondoren exekutatu systemctl start-ekin [posta elektroniko bidez babestua]: 1234.

Zabbixen aurkikuntza

Zabbix-ek martxan dauden zerbitzuak deskubritu ahal izateko, egina dago talde-zerrenda-sorgailua (discovery.sh), Zabbix aurkikuntzarako beharrezkoa den formatuan, leku berean dagoela suposatzen da - /opt/tsduck-stat-en. Zabbix-agent bidez aurkikuntza exekutatzeko, gehitu behar duzu .conf fitxategia zabbix-agent konfigurazio direktoriora erabiltzailearen parametroa gehitzeko.

Zabbix txantiloia

Sortu txantiloia (tsduck_stat_template.xml) aurkikuntza automatikoaren araua, elementuen prototipoak, grafikoak eta abiarazleak ditu.

Kontrol-zerrenda laburra (beno, norbaitek erabiltzea erabakitzen badu)

  1. Ziurtatu tsp-k ez dituela paketeak erortzen baldintza "idealetan" (sorgailua eta analizatzailea zuzenean konektatuta daude), tantak egonez gero, ikusi 2. paragrafoa edo gai honi buruzko artikuluaren testua.
  2. Egin sintonizatze socket buffer maximoa (net.core.rmem_max=8388608).
  3. Konpilatu tsduck-stat.go (joan tsduck-stat.go eraikitzera).
  4. Jarri zerbitzu txantiloia /lib/systemd/system-en.
  5. Hasi zerbitzuak systemctl-rekin, egiaztatu kontagailuak agertzen hasi direla (grep "" /dev/shm/tsduck-stat/*). Zerbitzu kopurua multicast korronte kopuruaren arabera. Hemen multicast talderako ibilbide bat sortu beharko duzu, agian rp_filter desgaitu edo iturburu iprako ibilbide bat sortu.
  6. Exekutatu discovery.sh, ziurtatu json sortzen duela.
  7. Gehitu zabbix agentearen konfigurazioa, berrabiarazi zabbix agentea.
  8. Kargatu txantiloia zabbix-era, aplikatu kontrolatzen ari den ostalariari eta zabbix-agentea instalatuta dago, itxaron 5 minutu inguru, ikusi elementu, grafiko eta abiarazle berriak dauden.

Emaitza

TSduck erabiliz IP(TS) korronteak monitorizatzeko

Pakete-galera detektatzeko zeregina ia nahikoa da, gutxienez monitorizaziorik ez baino hobea da.

Izan ere, CC "galerak" gerta daitezke bideo zatiak batzean (nik dakidanez, horrela egiten dira txertaketak Errusiako Federazioko tokiko telebista zentroetan, hau da, CC kontagailua berriro kalkulatu gabe), hau gogoratu behar da. Konponbide jabedunek arazo hau partzialki saihesten dute SCTE-35 etiketak detektatuz (korronte-sorgailuak gehitzen baditu).

Garraioaren kalitatearen monitorizazioari dagokionez, jitter monitoring (IAT) falta da. Telebistako ekipamenduak (izan modulatzaileak edo amaierako gailuak) parametro honetarako baldintzak ditu eta ez da beti posible jitbuffer-a infinituraino puztea. Eta jitter-ak flotatu egin dezake buffer handiak dituzten ekipoak garraioan erabiltzen direnean eta QoS ez dagoenean edo nahikoa ondo konfiguratuta ez dagoenean denbora errealeko trafiko hori transmititzeko.

Iturria: www.habr.com

Gehitu iruzkin berria