App-ReslirpTunnel
view release on metacpan or search on metacpan
lib/App/ReslirpTunnel/ElevatedSlave.pm view on Meta::CPAN
sub _hello__rpc {
return { status => "ok" }
}
sub _run {
my $self = shift;
while (1) {
$self->_log(debug => "Waiting for request");
my $request = $self->{rpc}->recv_packet();
my $cmd = $request->{cmd};
$self->_log(debug => "Received request: $cmd");
my $method = "_${cmd}__rpc";
my ($r, $fd);
eval {
$r = $self->$method($request->{args}) // {};
$r->{status} //= "ok";
$fd = delete $r->{fd};
if (defined $fd) {
$r->{fd_follows} = 1;
}
};
if ($@) {
$r = { status => "error", error => $@ };
}
$self->{rpc}->send_packet($r);
if (defined $fd) {
$self->{rpc}->send_fd($fd);
}
$self->_log(debug => "Request completed with status $r->{status}");
last if ($r->{status} eq 'bye');
}
$self->_log(info => "Bye bye!");
}
sub new {
my ($class, %args) = @_;
my $self = { socket => $args{socket} };
bless $self, $class;
$self->_init_logger(log_level => $args{log_level},
log_to_stderr => $args{log_to_stderr},
log_file => $args{log_file},
log_uid => $args{log_uid},
log_prefix => "ReslirpTunnel::ElevatedSlave");
$self->{rpc} = App::ReslirpTunnel::RPC->new($args{socket});
$self->_log(info => "Evalated slave started");
$self
}
sub _init_logger {
my ($self, %args) = @_;
# We need to open a different log file for the elevated slave as
# we are running under a different user (root) and don't have
# permission to write to the user's log file.
$args{log_file} =~ s/((?:\.[^\.]+)?)$/.elevated$1/ if defined $args{log_file};
$self->SUPER::_init_logger(%args);
}
sub _hex2arg {
my $hex = shift;
my $arg = pack("H*", $hex);
# warn "$hex --> $arg\n";
utf8::decode($arg);
return $arg;
}
sub start {
# Recover socket from the file descriptor passed by the parent
POSIX::dup2(1, 3);
POSIX::dup2(2, 1);
$SIG{INT} = 'IGNORE';
# Detach from the controlling terminal
POSIX::setsid();
my $pid = fork;
if (defined $pid and $pid == 0) {
my $socket = IO::Socket::UNIX->new_from_fd(3, "r+")
or die "Failed to create socket: $!";
my $dont_close_stdio = _hex2arg(shift @main::ARGV);
my $log_level = _hex2arg(shift @main::ARGV);
my $log_to_stderr = _hex2arg(shift @main::ARGV);
my $log_file = ($log_to_stderr ? undef : _hex2arg(shift @main::ARGV));
my $log_uid = ($log_to_stderr ? undef : _hex2arg(shift @main::ARGV));
unless ($dont_close_stdio) {
open STDIN, '<', '/dev/null';
open STDOUT, '>', '/dev/null';
open STDERR, '>', '/dev/null' unless $log_to_stderr;
}
my $server = __PACKAGE__->new(socket => $socket,
dont_close_stdio => $dont_close_stdio,
log_level => $log_level,
log_to_stderr => $log_to_stderr,
log_file => $log_file,
log_uid => $log_uid);
$server->_run();
}
POSIX::_exit(0);
}
1;
( run in 0.688 second using v1.01-cache-2.11-cpan-b301d465b3d )