POSTS

Telia Internet 2

Jätkan oma ruuteri seadistamist, mille kirjeldamist alustasin eelmises postituses.

Nagu selgus, on probleem Arris VIP1113 digiboxis, mis ei suuda näidata Telia filmiriiulit/lastenurka. Käivitamisel kuvab lihtsalt, et video käivitamine ebaõnnestus. Samas samsungi smart TV oskab. Uurisin natuke, kuidas see teenus üldse toimib. Tundub et tegu on lihtsalt RTSP kaudu streami küsimisega, mis oma olemuselt on HTTP laadne protokoll, aga socketit kinni ei panda pärast iga päringut. Ehk et tehakse TCP ühendus serverisse (vaikimisi on port 554), ning küsitakse video kohta infot ja samuti antakse käske SETUP, PLAY, PAUSE, TEARDOWN jne. ning server hakkab vastavalt saatma stream’i kliendi poole (Telia lahenduses UDP kaudu).

Installisin ruuterisse tcpflow nimelise utiliidi ja andsin käsu:

tcpflow -i lan1wan.4 -c dst port 554 or src port 554

Selle tulemusena kuvatakse ekraanil lan1wan.4 interfeisi kaudu käiv TCP liiklus, mille destination või source port on 554. Proovisin nii töötava samsungi smart TV’ga kui ka Arrise digiboxiga. Tulemused on järgmised (taandreaga on serveri vastus, ilma on kliendi päring):

Samsung smart TV:

OPTIONS rtsp://84.50.87.19/lotte_ja_kuukivi_saladus_hd_20130930_enc.mpg RTSP/1.0
CSeq: 0
	RTSP/1.0 200 OK
	Server: Orbit2x
	CSeq: 0
	Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER

DESCRIBE rtsp://84.50.87.19/lotte_ja_kuukivi_saladus_hd_20130930_enc.mpg RTSP/1.0
CSeq: 1
Accept: application/sdp
	RTSP/1.0 200 OK
	Server: Orbit2x
	CSeq: 1
	Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER
	Content-Type: application/sdp
	Content-Length: 174

	v=0
	o=- 675230 0 IN IP4 84.50.87.19
	s=RTSP Session
	t=0 0
	c=IN IP4 84.50.87.19
	b=AS:7277.000
	a=type:vod
	a=range:npt=0-4345
	m=video 0 UDP 33
	m=video 0 RTP/AVP/UDP 33

SETUP rtsp://84.50.87.19/lotte_ja_kuukivi_saladus_hd_20130930_enc.mpg/ RTSP/1.0
CSeq: 2
Transport: RAW/RAW/UDP;unicast;client_port=54020-54021;mode=play
	RTSP/1.0 200 OK
	Server: Orbit2x
	CSeq: 2
	Session: 3906656268761771184;timeout=60
	Transport: RAW/RAW/UDP;unicast;destination=10.242.255.160;client_port=54020;source=84.50.87.19;server_port=10000

PLAY rtsp://84.50.87.19/lotte_ja_kuukivi_saladus_hd_20130930_enc.mpg RTSP/1.0
CSeq: 3
Session: 3906656268761771184
Range: npt=0.000-
Scale:   1.0
	RTSP/1.0 200 OK
	Server: Orbit2x
	CSeq: 3
	Session: 3906656268761771184
	Scale: 1.00
	Range: npt=0-

Arris VIP1113:

OPTIONS rtsp://84.50.87.19:554/lotte_ja_kuukivi_saladus_hd_20130930_enc.mpg RTSP/1.0
CSeq: 1
	RTSP/1.0 200 OK
	Server: Orbit2x
	CSeq: 1
	Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER

DESCRIBE rtsp://84.50.87.19:554/lotte_ja_kuukivi_saladus_hd_20130930_enc.mpg RTSP/1.0
Accept: application/sdp
CSeq: 2
	RTSP/1.0 200 OK
	Server: Orbit2x
	CSeq: 2
	Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER
	Content-Type: application/sdp
	Content-Length: 174

	v=0
	o=- 675849 0 IN IP4 84.50.87.19
	s=RTSP Session
	t=0 0
	c=IN IP4 84.50.87.19
	b=AS:7277.000
	a=type:vod
	a=range:npt=0-4345
	m=video 0 UDP 33
	m=video 0 RTP/AVP/UDP 33

SETUP rtsp://84.50.87.19:554/lotte_ja_kuukivi_saladus_hd_20130930_enc.mpg RTSP/1.0
User-Agent: Kreatel_IP-STB
Transport: MP2T/H2221/UDP;unicast;destination=192.168.1.146;client_port=56198
x-properties: mac_address=12345678ABCD
x-mayNotify:
CSeq: 3
	RTSP/1.0 403 Forbidden
	Server: Orbit2x
	CSeq: 3

Analüüsides nüüd neid kahekõnesid, tundub mulle, et Arris saab sellepärast tala, et ta palub hakata streamima enda sisevõrgu aadressile 192.168.1.146. Mõistagi ei tea Telia server sellest aadressist midagi, ning keeldub sinna streamimast. Kusjuures samsungi telekas jätab oma aadressi lihtsalt panemata, ütleb ainult pordi(d) kuhu võiks streamida, ning server siis automaatselt eeldab, et vaja on saata tema poolt nähtud aadressile, ehk siis ruuteri lan1wan.4 interfeisi aadressile. See pani mind mõtlema, et äkki saaks ehitada mingi proxy laadse softikese, mis koristaks Arrise puhul selle aadressi lihtsalt ära.

Lisaks tuleb tähelepanu pöörata sellele, et ega see stream sealt serverist niisama läbi sinu ruuteri jooksma ei hakka, sest ruuter ei tea kuhu tuleks vastavad UDP paketid edasi saata. Selleks teeb samsungi telekas sellist trikki, et saadab kõigepealt mõne UDP paketi vastupidises suunas (telekast serverisse, RTSP peal kokkulepitud endpoint portidega). Kuna ruuter teeb NAT’i, siis ta jätab selle liikluskoridori meelde, ja selle tulemusena jõuab stream õige sisevõrgu seadmeni. Täpselt sama teeb muide ka linuxi mplayer. Arrise puhul jään vastuse võlgu, sest ma ei proovinud. Aga seda loogikat on vaja teada, et softi kirjutada.

Nüüd softist. Kirjutasin väikese utiliidi, mis teeb järgmist:

  • Kuulab ruuteris TCP porti 554 ja võtab vastu RTSP ühendusi.
  • Ühenduse saabudes loeb protokollist esimese rea, ning üritab parsida, kuhu telekas tahtis tegelikult ühendust teha.
  • Kui parsimine ebaõnnestub, siis teeb ühenduse vaikimisi käsurealt antud serverisse.
  • Edasi ta vahendab lihtsalt teleka ja serveri vahelist kahekõnet, kuid jälgib teatud mustrit.
  • Kui avastab, et telekas on saatnud serveri poole rea, kus on kirjeldatud streami destination aadress, siis eemaldab selle ning saadab selle konkreetse rea ilma destinationita.
  • Samuti kuulab ta serverist teleka poole saadetavaid ridu ning üritab avastada serveri kinnitust, kuhu ta streami hakkab saatma.
  • Kui on teada streami endpointid, siis lisab linuxi iptables’isse kirje, mis käsib ruuteril suunata vastavad UDP paketid õigele sisevõrgu seadmele.
  • Kui ühendus kinni pannakse ja oli jõutud kirjeldada iptables’i kirje, siis eemaldatakse antud kirje.
  • Kui ühendus on pikka aega idle, siis pannakse ise ühendus kinni ja vajadusel eemaldatakse iptables’i kirje.

Alguses kaalusin iptables’i reegli asemel käsitsi lisada “connection tracking”, aga ma ei olnud sellega kokku puutunud ja ei saanud seda lihtsate näidete baasil tööle. Samuti ei ole ma kindel, kas ma üldse õiget asja uurisin. Selle eelis oleks olnud see, et kernelil oleks siis enda sisemine timeout, millal ta selle koridori ära kustutab. Sest praeguse lahenduse puhul on oht, et kui iptables’i reegel on kirjeldatud ja soft kas kokku jookseb või käsitsi ära tappa, siis ei kustuta keegi antud reeglit ära. Igaks juhuks lisasin reegli kirjeldamisel ka kommentaari, mis pannakse reegli juurde, ning kommentaaris on kirjas linuxi uptime väärtus reegli lisamisel. Selle alusel saaks mingi skriptiga aegunud reegleid kustutada kui tarvis.

Teoreetiline oht on veel selline, et kui mõlemad telekad juhuslikult valivad samal ajal streamimiseks sama pordi, siis tekib mingit sorti konflikt. Aga selle vastu ma ei viitsi võidelda, selle tõenäosus on suhteliselt olematu, ning kui see isegi juhtub, siis ei hakka video lihtsalt mängima. Saad puldist uuesti käima panna ja siis on juba teine port kuulamiseks võetud.

Selleks aga, et TCP ühendused jõuaks kõigepealt ikkagi ruuterisse, mitte otse serverisse, anname iptables’i käsu:

/sbin/iptables -I PREROUTING -t nat -p tcp -d 84.50.87.0/24 --dport 554 -j DNAT --to 192.168.1.1:554

Ehk et kõik TCP ühendused mis lähevad võrku 84.50.87.0/24 ja pordile 554, tuleb ümber suunata aadressile 192.168.1.1 (mis on minu puhul ruuteri sisevõrgu poolne aadress).

Ning siis paneme softi käima parameetritega:

/sbin/rtsp_proxy 192.168.1.1 554 84.50.87.91 554 300

rtsp_proxy on kompileeritud softi jupike, ning parameetrid on vastavalt järjest:

  • aadress, kuhu ennast kuulama sätitakse (mõistlik oleks, et ta kuulab ainult sisevõrgu poolt)
  • port mida kuulatakse
  • vaikimisi serveri aadress, kuhu ühendutakse juhul kui ei suudetud parsida aadressi
  • vaikimisi serveri port, kuhu ühendutakse juhul kui ei suudetud parsida porti
  • timeout sekundites pärast mida pannakse ühendus kinni, kui ei ole liiklust olnud

Huvitav tähelepanek on, et server ei kontrolli tegelikult RTSP headeris oleva aadressi vastavust tegelikkusega. Testimise käigus ühendusin kogemata vale serveriga, ning server rõõmsasti hakkas sama faili striimima. Kahtlustan, et Telial on lihtsalt hulk servereid load balancingu jaoks ning kõikides pakutakse samu faile. Seda võib järeldada ka sellest, et mingi kindla video vaatamiseks pöördutakse erinevatel kordadel erinevate serverite poole.

Pärast kogu seda tralli töötab Arrise box kenasti. Muidugi läheb nüüd ka samsungi telekas läbi selle proxy, kuid see tema töötamist ei sega. Proxi liiklus on väga hõre, niiet ei teki ka mingit viivitust. Õnneks nii samsungi telekas kui Arrise box küsivad ka regulaarselt video vaatamise käigus infot video kohta, mis hoiab socketi ühendused püsti.

Soft on saadaval siin:

https://bitbucket.org/rebane/rtsp_telia

Kompileerimiseks on vaja anda käsk make.

Soft eeldab, et süsteemis on saadaval iptables nimeline käsk ning kasutab seda väliselt.

Comments

Leave a comment