App-ReslirpTunnel

 view release on metacpan or  search on metacpan

lib/App/ReslirpTunnel.pm  view on Meta::CPAN

        $self->_log(info => "Starting dnsmasq");

        my $pid_parent_dir = $self->{xdg}->state_home->child('dnsmasq')->mkdir;
        my $pid_fn = $pid_parent_dir->child($self->{timestamp}.".dnsmasq.pid");
        my $latest_fn = $pid_parent_dir->child("latest.dnsmasq.pid");
        unlink $latest_fn if -e $latest_fn;
        symlink $pid_fn, $latest_fn;
        my $log_fn = $self->{xdg}->state_home->child('logs')->mkdir->child($self->{timestamp}.".dnsmasq.log");
        my $butler = $self->{butler};
        my $user_name = $self->_get_user_name;
        my $group_name = $self->_get_group_name;
        my $pid = $self->{dnsmasq_pid} = $butler->start_dnsmasq(device => $self->{tap_device},
                                                                net_mapping => $net_mapping,
                                                                forward_dns => $forward_dns,
                                                                user => $user_name,
                                                                group => $group_name,
                                                                pid_fn => "$pid_fn",
                                                                log_fn => "$log_fn");
        if ($pid) {
            $self->_log(debug => "dnsmasq PID", $pid);
        }
        else {
            $self->_warn("dnsmasq failed to start correctly, no PID found");
        }
    }
    else {
        $self->_log(debug => 'dnsmasq not required');
    }
}

sub _init_resolver_rules {
    my $self = shift;
    my @domains = ( keys(%{$self->{net_mapping}}),
                    keys(%{$self->{forward_dns}}) );
    if(@domains) {
        $self->_log(info => "Setting up resolver rules");
        my $butler = $self->{butler};
        my $device = $self->{tap_device};
        my $local_ip = $self->{local_ip};
        $butler->resolvectl_dns(device => $device, dns => $local_ip);
        for my $domain (@domains) {
            $butler->resolvectl_domain(device => $device, domain => $domain);
        }
    }
}

sub _init_routes {
    my $self = shift;
    my $forward = $self->{forward_ipv4};
    if (%$forward) {
        $self->_log(info => "Setting up routes");
        my $butler = $self->{butler};
        for my $net (keys %$forward) {
            $butler->route_add(net => $net, gw => $self->{remote_gw}, device => $self->{tap_device});
        }
    }
}

sub _get_user_name {
    my $self = shift;
    my $user = getpwuid($<);
    return $user if $user;

    $self->_warn("Failed to get user name, using 'nobody'");
    return 'nobody';
}

sub _get_group_name {
    my $self = shift;
    my $group = getgrgid($();
    return $group if $group;

    $self->_warn("Failed to get group name, using 'nogroup'");
    return 'nogroup'
}

sub _init_loop {
    my $self = shift;

    my $loop = App::ReslirpTunnel::Loop->new(log_level => $self->{log_level},
                                           log_to_stderr => $self->{log_to_stderr},
                                           log_file => $self->{log_file});

    my $pid = $loop->run($self->{tap_fh}, $self->{reslirp_socket}, $self->{reslirp_stderr})
        //$self->_die("Failed to start IO loop process");

    $self->_log(info => "IO loop process started, PID: $pid");
    $self->{loop_pid} = $pid;
}

sub _find_process_by_pid {
    my ($self, $pid) = @_;
    for my $process (qw(reslirp loop dnsmasq)) {
        my $process_pid = $self->{"${process}_pid"};
        if (defined $process_pid) {
            return $process if $self->{"${process}_pid"} == $pid;
        }
    }
    return;
}

sub _wait_for_something {
    my $self = shift;
    $self->_log(debug => "Waiting for some child to exit");
    while (not ${$self->{signal_count_ref}}) {
        my $kid = waitpid(-1, WNOHANG);
        if ($kid <= 0) {
            # $self->_log(debug => "waitpid", $kid);
            $self->_log(debug => "waitpid failed", $!) if $kid < 0;
            select undef, undef, undef, 5;
        }
        else {
            $self->_log(debug => "process $kid exited, rc", $? >> 8);
            for my $proc (qw(reslirp loop ssh_master)) {
                my $proc_pid = $self->{"${proc}_pid"};
                if (defined $proc_pid and $kid == $proc_pid) {
                    $self->_log(info => "Process $proc (PID: $kid) finished");
                    delete $self->{"${proc}_pid"};

                    $self->{ssh}->master_exited if $proc eq 'ssh_master';
                    return;



( run in 1.741 second using v1.01-cache-2.11-cpan-364913b4093 )