📄 norelay.xpl
字号:
<?xml version="1.0"?><!DOCTYPE methoddef SYSTEM "rpc-method.dtd"><methoddef><name>NoRelay</name><version>1.0</version><signature>struct struct</signature><help>Accepts a struct containing KEY VALUE Program string (URI of the program) Postreq string the CGI to be invoked before AuthToken int token to authenticate method callerReturns a struct containing KEY VALUE ret_code int (numeric return code) ret_val string (message string)</help><code language="perl"><![CDATA[#!/usr/bin/perl################################################################################ Sub Name: NoRelay## Accepts KEY VALUE# Program string (URI of the program)# Postreq the CGI to be invoked before# AuthToken token to authenticate method caller## Returns KEY VALUE# ret_code int (numeric return code)# ret_val string (message string)###############################################################################sub NoRelay { use Net::IPv4Addr qw( :all ); use CommLib qw(children_wait DBF_access chk_resp node_log); require "$Node::opt_c"; NodeConfig->import(qw($node_address $node_port)); my $refstr = pop @_; my $prog = $$refstr{Program}; my $postreq = $$refstr{Postreq}; my $hisToken = $$refstr{AuthToken}; my ($ret_val, $ret_code) = (undef, undef); my ($auth_token, $transp, $res) = (undef, undef, undef); # Retrieves AuthToken and transport for this program from DB file my $auth_t_r = DBF_access ("$Node::us_URI_db", ['AuthToken', "tra_$prog"], 'r', 'n'); $auth_token = $$auth_t_r{'AuthToken'}; $transp = $$auth_t_r{"tra_$prog"}; if ($auth_token && $transp) { # values retrieved if ( $hisToken ne $auth_token ) { # caller unauthorized $ret_code = '401'; $ret_val = 'Unauthorized'; node_log ("[$node_address]:NoRelay: $ret_code $ret_val", 1, 'n'); } } else { # auth_token NOT retrieved $ret_code = '408'; $ret_val = 'Unable to retrieve AuthToken/transport from DB_File'; node_log (": [$node_address]:NoRelay: $ret_code $ret_val", 1, 'n'); } unless ($ret_code) { # Node is authorized node_log ("[$node_address] > Receiving NoRelay req for prog $prog", 1, 'n' ); # checks if origin format is correct if ( $prog !~ m/rtsp:\/\/.*\//) { $ret_val = 'Bad program format'; $ret_code = '420'; node_log ( "$ret_val", 1, 'n'); } } unless ($ret_code) { # program format is correct node_log ( "[$node_address] ...program format is ok", 3, 'n' ); # Propagates TearDown toward downstream peers if any if ( $NodeLib::peers_by_prog{$prog} ) { my ($peer, @peers, $cico, %children, $peer_IP, $peer_prt, $i) = (undef, undef, 0, undef, undef, undef, undef); my $nodepid = $$; #node_log ( " Wow! So this is a multilevel teardown!", 3, 'n'); @peers = keys %{$NodeLib::peers_by_prog{$prog}}; node_log ( "[$node_address]'s peers are: @peers", 3, 'n'); foreach $peer ( keys %{$NodeLib::peers_by_prog{$prog}} ) { ( $peer_IP, $peer_prt ) = split /:/, $peer; if ($pid = fork ) { # father here $cico++; $children{$pid} = "$peer_IP:$peer_prt"; node_log ("[$node_address] forked PID $pid for peer [$peer_IP]", 3, 'n'); } else { # child here node_log ( "[$node_address] (pid $$) sends NoRelay to [$peer_IP]", 1, 'n'); my $cli = RPC::XML::Client->new("http://$peer_IP:$peer_prt", 'useragent', ['timeout', 60]); ($ret_code, $ret_val) = &NodeLib::chk_resp ($cli, $peer_IP, 'n'); unless ($ret_code) { # Do the request $res = $cli->send_request('NoRelay', { Program => $prog, AuthToken => $auth_token }); ($ret_code, $ret_val) = chk_resp ($res, $peer_IP, 'r'); if ( ( $ret_code eq '200' ) || ( $ret_code eq '220' ) ) { $ret_code = '200'; $ret_val = "[$node_address] ($$) peer [$peer_IP] NoRelay ok"; } else { # not a good response $ret_code = '520'; $ret_val = "WARNING: bad asnw from [$peer_IP]" . "$ret_code $ret_val"; } } else { # XML-RPC client didn't opens $ret_code = '520'; $ret_val = "WARNING: ($$)'s peer [$peer_IP] don't opens:" . "$ret_code $ret_val"; } node_log ( "$ret_val", 1, 'n'); exit; } # child ends here } # end foreach peer } # end if recursive TearDown else { # I was a LH. Decrements LHmemory counter $NodeLib::LHmemory-- if ($NodeLib::LHmemory > 0); } # Removes Streaming Server's credentials ( $ret_code, $ret_val ) = &Adaptation::rem_RTSP_credentials ($transp); if ( $ret_code ne '200' ) { node_log ( "$ret_val", 1, 'n'); # not a good answer $ret_val = "[$node_address:$node_port] said: $ret_val\n"; return { ret_code => $ret_code, ret_val => $ret_val }; } # Destroys the local relay my $relayname = $NodeLib::relay_by_prog{$prog}; node_log ( "[$node_address] ...dismantling local relay $relayname", 1, 'n'); ($ret_code, $ret_val) = &Adaptation::no_relay ( $relayname, $Node::us_URI_db); node_log ( "[$node_address] Adaptation: $ret_code $ret_val", 1, 'n' ); # Destroys local data structures my $surrog = $NodeLib::surr_by_prog{$prog}; delete $NodeLib::prog_by_relay{$relayname}; delete $NodeLib::relay_by_prog{$prog}; delete $NodeLib::surr_by_prog{$prog}; delete $NodeLib::tran_by_relay{$relayname}; # Deletes the current Upstream Origin and transport for program $prog my $hr = DBF_access ("$Node::us_URI_db", ["tra_$prog"], 'd', 'n'); unless (%$hr) { node_log (": [$node_address]:NoRelay: problems with DB_File :-(", 1, 'n'); } $hr = DBF_access ("$Node::us_URI_db", [$prog], 'd', 'n'); unless (%$hr) { node_log (": [$node_address]:NoRelay: problems with DB_File :-((", 1, 'n'); } # waits for downstream teardowns if any if ( $NodeLib::peers_by_prog{$prog} ) { node_log ( "[$node_address] Waiting for ($cico) peer children to return..." , 1, 'n'); children_wait (\%children, 'n'); node_log ( "[$node_address] Peer children returned!", 3, 'n'); delete $NodeLib::peers_by_prog{$prog}; } } # ends unless program format ok return { ret_code => $ret_code, ret_val => $ret_val };}__END__]]></code></methoddef>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -