Captive-Portal

 view release on metacpan or  search on metacpan

lib/Captive/Portal/Role/Firewall.pm  view on Meta::CPAN


      INFO "$user/$ip/$mac -> stopped, MAX_SESSION limit";

      my $error;
      try { $self->fw_stop_session($ip) } catch { $error = $_ };

      ERROR $error if $error;

      $session->{STATE}     = 'max-session-timeout';
      $session->{STOP_TIME} = $this_run;

      undef $error;
      try {
        $self->write_session_handle( $lock_handle, $session );
      }
      catch { $error = $_ };

      ERROR $error if $error;

      next;    # session
    }

    next unless $session->{STATE} eq 'active';

    ################################################################
    # below this point we handle only sessions with STATE = active
    ################################################################

    ###########################################################
    # ipset-entry was missing for current session at
    # mainloop entry. Maybe it was a race condition.
    # Check if there is still no ipset-entry for this session
    # now we have the lock.
    #
    # We don't check this unconditionally for every session,
    # this would be to expansive for thousand of clients.
    ###########################################################

    if (  ( not defined $fw_session_entry )
      and ( not defined $self->fw_list_sessions->{$ip} ) )
    {

      WARN "$user/$ip/$mac -> delete session, ipset-entry missing";

      my $error;
      try { $self->delete_session_from_disk($ip); } catch { $error = $_ };

      ERROR $error if $error;

      next;    # session
    }

    ###########################################################
    ###########################################################
    # now start with the IDLE check for this active session
    ###########################################################
    ###########################################################

    ###########################################################
    # packets seen from this client within last IDLE_TIME period?
    # the capo_activity_ipset has the internal countdown timer
    # set with IDLE_TIME, great thanks to the ipset developers!
    ###########################################################

    next if exists $fw_activity->{$ip};

    ###########################################################
    ###########################################################
    # after that the client wasn't seen for IDLE_TIME
    ###########################################################
    ###########################################################

    INFO "$user/$ip/$mac -> session is IDLE";

    $session->{STATE}     = 'idle';
    $session->{STOP_TIME} = $this_run;

    undef $error;
    try {
      $self->fw_stop_session($ip);
      $self->write_session_handle( $lock_handle, $session );
    }
    catch { $error = $_ };
    ERROR $error if $error;

    next;    # session

  }    # session mainloop end

  ###########################################################
  # Handle remaining ipset session entries with
  # no corresponding session file. Be careful,
  # maybe a race condition between purger and fcgi script
  # was the reason for that inconsistency
  ###########################################################

  foreach my $ip ( keys %{$fw_sessions} ) {

    # check if there is still no session file for that ipset entry
    #
    my ( $lock_handle, $error );
    try {

      # get the EXCL lock for the session
      # hold this lock until next loop iteration
      #
      $lock_handle = $self->get_session_lock_handle(
        key      => $ip,
        blocking => 1,
        shared   => 0,
        timeout  => 50_000,    # 50_000 us -> 50ms
      );

    }
    catch { $error = $_ };

    if ($error) {
      WARN $error;
      next;
    }



( run in 1.897 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )