📄 setup.xpl
字号:
<?xml version="1.0"?><!DOCTYPE methoddef SYSTEM "rpc-method.dtd"><methoddef><name>Setup</name><version>1.1</version><signature>string struct</signature><help>Description: Return to the Requestor the surrogate-UriArguments: an structure containing: KEY VALUE Client IP Address of the requesting client Program Source URI of the contentReturns: an hash reference KEY Value ret_code 200 for success, 302 for XML-RPC errors, 404 if no Last Hop candidate is found, or the code returned by the node ret_val a string with the surrogate URI or error details Prereq_Res Prerequisite response page</help><code language="perl"><![CDATA[#!/usr/bin/perluse File::Flock;use Net::IPv4Addr qw(ipv4_in_network);use CommLib qw(node_log find_best);use etc::CommConf qw($rrdm_addr $rrdm_port $log_to);################################################################################# Sub Name: Setup## Description: Return to the Requestor the surrogate-Uri## Arguments: a structure containing:# KEY Value# Client IP Address of the requesting client# Program Source URI of the content## Returns: an hash reference# KEY Value# ret_code 200 for success,# 302 for XML-RPC errors,# 404 if no Last Hop candidate is found,# 405 if invalid call parameters,# or the code returned by the node# ret_val a string with the surrogate URI or error details# Prereq_Res Prerequisite response page################################################################################sub Setup {my ($ret_code, $ret_val, $surr_URI) = ('', '', '');my ($LH_sn_r, $TR_sn_r, $LH_sFP_r, $TR_sFP_r, $LH_spo_r, $TR_spo_r) = ((), (), (), (), (), ());my ($LH_cn_r, $TR_cn_r, $LH_cFP_r, $TR_cFP_r, $LH_cpo_r, $TR_cpo_r) = ((), (), (), (), (), ());my ($cli, $mret_ref, $prereq_res) = ('', '', '');my ($i, $j, $cnode, $cFP) = (undef, '', '');my $att_ref = pop @_;my $client = $$att_ref{Client};my $program = $$att_ref{Program};node_log ( "*** Setup method entered for client $client, program $program", 1, 'r');if (!$program) { ($ret_code, $ret_val) = ('405', 'Invalid SetUp parameters. Please notify developers about how this occurred.'); node_log ($ret_val, 1, 'r'); return { ret_code => $ret_code, ret_val => $ret_val};}my $transport = &RRDMlib::origins("{'$program'}{'transport'}");my $OriginAddr = &RRDMlib::origins("{'$program'}{'ip'}");my $prereq = &RRDMlib::origins("{'$program'}{'prereq'}");if (defined $main::forked) { lock ($client); # dont same client twice node_log ( "* ... lock on $client acquired by pid $$", 3, 'r');}# Look for candidate LH/transit nodes with a footprint that contain the client.# Hint about returned variables: <LH> and <TR> is for LastHop and TRansit,# <cn> for candidate node, <cFP> for cand. FootPrint, <cpo> cand. portnode_log (" * Checking LastHop and TRansit Candidates", 2, 'r');($LH_cn_r, $TR_cn_r, $LH_cFP_r, $TR_cFP_r, $LH_cpo_r, $TR_cpo_r) = &RRDMlib::Find_Nod ($client, $transport, '', 0); #if (&RRDMlib::surro("{'$program'}")) { # Surr. already exists in client FP? # node_log (" * Checking for LastHop or Transit surrogates", 2, 'r'); ($LH_sn_r, $TR_sn_r, $LH_sFP_r, $TR_sFP_r, $LH_spo_r, $TR_spo_r) = &RRDMlib::Find_Nod ($client, $transport, $program, 0); node_log (" - Surrogates found: LH @$LH_sn_r, TR @$TR_sn_r", 1, 'r'); node_log (" - with FootPrints: @$LH_sFP_r, @$TR_sFP_r", 2,'r'); # if (@$LH_sn_r) { # Some LH surrogates do exists # node_log (" * Some LH surrogates do exists. Probing...", 1, 'r'); $i = find_best($LH_sn_r, $LH_spo_r, $LH_sFP_r, $program, $rrdm_addr, '0', 'r'); if ($i>=0) { # a LH surrogate answered # tryes if LH candidates more specific than LH surrogates do exist my ($LH_sno, $LH_sFP) = ($$LH_sn_r[$i], $$LH_sFP_r[$i]); for ($j=0; $j<@$LH_cn_r; $j++) { # All the LH candidates ($cnode, $cFP) = ($$LH_cn_r[$j], $$LH_cFP_r[$j]); if ($cnode ne $LH_sno && $cFP ne $LH_sFP && ipv4_in_network ($LH_sFP, $cFP)) { $ret_code = '230'; $ret_val = "Cand. LH $cnode FP ($cFP) is contained in LH $LH_sno surr. FP ($LH_sFP)"; node_log ( " * $ret_val", 1, 'r'); last; } } unless ($ret_code eq '230') { # no more specific LH cand exists my $s_uri = &RRDMlib::surro("{'$program'}{'$LH_sFP'}{'$LH_sno'}[0]"); node_log ( " * Found $s_uri LH surrogate already available", 1, 'r'); $ret_code = '200'; $ret_val = $s_uri; } } else { $ret_code = '504'; $ret_val = "Last Hop surrogate(s) @$LH_sn_r don\'t answer for $client"; node_log ( " * $ret_val", 1, 'r'); &RRDMlib::suri_del ($program, $LH_sn_r, $LH_sFP_r); } }} #unless ($ret_code eq '200') { # No LH surr. already exist. Need a new one # node_log (" * No valid surrogate LH already exists for client $client", 1, 'r'); node_log (" - Candidates found: LH @$LH_cn_r, TR @$TR_cn_r", 1, 'r'); node_log (" with FootPrints: @$LH_cFP_r, @$TR_cFP_r", 2,'r'); # if (@$LH_cn_r) { # at least, LH candidates must exist ! # my $parms = { Client => $client, # needed by DoRelay inside of mk_surr Transport => $transport, Program => $program, # the "absolute" origin Origin => $program, # where nodes should attach PreReq => $prereq, # CGI to call by FH before the DoRelay AuthToken => $RRDMlib::auth_token # Authentication token }; # Look for local FH: nodes whose LH_FP embraces the content Origin # Also, finds nodes whose TR_FP embraces the origin # Search is limited to /24 or narrower FP, thus eliminating global FP nodes my ($FH_cn_r, $FH_cTR_r, $FH_cFP_r, $FH_cTR_FP_r, $FH_cpo_r, $ph) = &RRDMlib::Find_Nod ($OriginAddr, $transport, '', 24); node_log (" * There can be additional local FH nodes: @$FH_cn_r", 1, 'r'); node_log (" with FP: @$FH_cFP_r", 2, 'r'); node_log (" - and these are Origin-related TRs: @$FH_cTR_r", 1, 'r'); node_log (" with FP: @$FH_cTR_FP_r", 2, 'r'); # Checks that there is no node that is both a local FH and a TR my ($cn_r, $FP_r, $po_r) = (undef, undef, undef); # hold temp values my ($found, $FH_FP, $TR_FP); # At first, checks whether a local FH is also a TR with a wider footprint, # and in that case it is removed from FH. This avoids that a world-wide TR # (i.e. with a dir -/2 and indir -/1 FP) everytime becomes a local FH. # The check is made by using Origin-related TR FP, because the client-related # ones may not overlap for ($i=0; $i<@$FH_cn_r; $i++) { # All the local FH candidates $found = undef; $FH_FP = $$FH_cFP_r[$i]; # local FH FootPrint for ($j=0; $j<@$FH_cTR_r; $j++) { # All the existing TR candidates if ($$FH_cn_r[$i] eq $$FH_cTR_r[$j]) { # local FH is also a TR if (ipv4_in_network ($$FH_cTR_FP_r[$j], $FH_FP)) { $found = 'yes'; # local FH has a FP contained last; # in a TR's one } } } unless ($found) { # LH isn't also a less spec TR push @$cn_r, $$FH_cn_r[$i]; # add LH to temp arrays push @$FP_r, $$FH_cFP_r[$i]; push @$po_r, $$FH_cpo_r[$i]; } } $FH_cn_r = $cn_r; # swap temp to FH arrays $FH_cFP_r = $FP_r; $FH_cpo_r = $po_r; ($cn_r, $FP_r, $po_r) = (undef, undef, undef); # clean temp values node_log (" - ... after wider TR pruning, local FH are: @$FH_cn_r", 2, 'r'); node_log ("- ... with FP and ports: @$FH_cFP_r, @$FH_cpo_r", 3, 'r'); # Then, checks whether i-th TR is also a local FH, and removes it from TR list for ($i=0; $i<@$TR_cn_r; $i++) { # All the existing TR candidates $found = undef; for ($j=0; $j<@$FH_cn_r; $j++) { # All the reamining local FH if ($$TR_cn_r[$i] eq $$FH_cn_r[$j]) { # local FH is also a TR $found = 'yes'; # local FH has a FP contained last; # in a TR's one } } unless ($found) { # TR doesn't appear as a FH also push @$cn_r, $$TR_cn_r[$i]; # add TR to temp arrays push @$FP_r, $$TR_cFP_r[$i]; push @$po_r, $$TR_cpo_r[$i]; } } $TR_cn_r = $cn_r; # swap temp to TR arrays $TR_cFP_r = $FP_r; $TR_cpo_r = $po_r; node_log (" - ... after local FH pruning, TR are: @$TR_cn_r", 2, 'r'); node_log ("- ... with FP and ports: @$TR_cFP_r, @$TR_cpo_r", 3, 'r'); # FirstHop nodes take the least specific FootPrint for ($i=0; $i<@$FH_cn_r; $i++) { node_log (" ..turning $$FH_cn_r[$i] FP to 0.0.0.0/0", 3, 'r'); $$FH_cFP_r[$i] = '0.0.0.0/0'; } push @$TR_cn_r, @$FH_cn_r; # Append at bottom as least specific push @$TR_cFP_r, @$FH_cFP_r; push @$TR_cpo_r, @$FH_cpo_r; node_log (" - ... so now TR and FP are: @$TR_cn_r, @$TR_cFP_r", 1, 'r'); if (!@$TR_sn_r && !@$TR_cn_r) { # no surr or cand Transit exists node_log ( " - Trying LH candidate nodes @$LH_cn_r", 1, 'r'); ($ret_code, $ret_val, $prereq_res) = &RRDMlib::mk_surr ($LH_cn_r, $LH_cpo_r, $LH_cFP_r, 'more2less', $parms); } # else { # we have Transits # $$parms{'LH_cn'} = $LH_cn_r; $$parms{'LH_cFP'} = $LH_cFP_r; # communicates Last Hop candidates $$parms{'TR_cn'} = $TR_cn_r; # and Transit addresses and FP $$parms{'TR_cFP'} = $TR_cFP_r; $$parms{'OriginAddr'} = $OriginAddr; # needed by DoRelay at FH nodes if (@$TR_sn_r) { # surrogate Transits exist: ask them $$parms{'Origin'} = ''; # to be filled by surr. with local Mount Point node_log ( " - Trying TR surrogate nodes @$TR_sn_r", 1, 'r'); ($ret_code, $ret_val, $prereq_res) = &RRDMlib::mk_surr ($TR_sn_r, $TR_spo_r, $TR_sFP_r, 'more2less', $parms, $LH_cpo_r, $TR_cpo_r); } unless (($ret_code eq '200') || !@$TR_cn_r) { # surr TR failed or absent: # try candidate TR if exist $$parms{'Origin'} = $program; # candidates keep from sources node_log ( " - Trying TR candidate nodes @$TR_cn_r", 1, 'r'); ($ret_code, $ret_val, $prereq_res) = &RRDMlib::mk_surr ($TR_cn_r, $TR_cpo_r, $TR_cFP_r, 'less2more', $parms, $LH_cpo_r, $TR_cpo_r); } } } else { # No LH candidate found $ret_code = '404'; $ret_val = "No LH candidate found with FP nice to $client and transport good for $program"; node_log ($ret_val, 1, 'r'); }}if (defined $main::forked) { node_log ( " * ... lock on $client released by pid $$", 3, 'r'); unlock($client);}return { ret_code => $ret_code, ret_val => $ret_val, Prereq_Res => $prereq_res};}__END__]]></code></methoddef>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -