github.com/aergoio/aergo@v1.3.1/p2p/list/listmanager.go (about)

     1  /*
     2   * @file
     3   * @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package list
     7  
     8  import (
     9  	"errors"
    10  	"github.com/aergoio/aergo-lib/log"
    11  	"github.com/aergoio/aergo/config"
    12  	"github.com/aergoio/aergo/contract/enterprise"
    13  	"github.com/aergoio/aergo/p2p/p2pcommon"
    14  	"github.com/aergoio/aergo/types"
    15  	"net"
    16  	"strings"
    17  	"sync"
    18  	"time"
    19  )
    20  
    21  // variables that are used internally
    22  var (
    23  	NotFoundError = errors.New("ban status not found")
    24  	UndefinedTime = time.Unix(0, 0)
    25  	FarawayFuture = time.Date(99999, 1, 1, 0, 0, 0, 0, time.UTC)
    26  )
    27  
    28  const (
    29  	localListFile = "list.json"
    30  )
    31  
    32  type listManagerImpl struct {
    33  	logger    *log.Logger
    34  	chainAcc  types.ChainAccessor
    35  	prm       p2pcommon.PeerRoleManager
    36  	publicNet bool
    37  
    38  	entries []types.WhiteListEntry
    39  	enabled bool
    40  	rwLock  sync.RWMutex
    41  	authDir string
    42  
    43  	stopScheduler chan interface{}
    44  }
    45  
    46  func NewListManager(conf *config.AuthConfig, authDir string, chainAcc types.ChainAccessor, prm p2pcommon.PeerRoleManager, logger *log.Logger, publicNet bool) p2pcommon.ListManager {
    47  	bm := &listManagerImpl{
    48  		logger:    logger,
    49  		chainAcc:  chainAcc,
    50  		prm:       prm,
    51  		publicNet: publicNet,
    52  
    53  		authDir:       authDir,
    54  		stopScheduler: make(chan interface{}),
    55  	}
    56  
    57  	return bm
    58  }
    59  
    60  func (lm *listManagerImpl) Start() {
    61  	lm.logger.Debug().Msg("starting up list manager")
    62  
    63  	lm.RefineList()
    64  }
    65  
    66  func (lm *listManagerImpl) Stop() {
    67  	lm.logger.Debug().Msg("stopping list manager")
    68  }
    69  
    70  func (lm *listManagerImpl) IsBanned(addr string, pid types.PeerID) (bool, time.Time) {
    71  	// empty entry is
    72  	if len(lm.entries) == 0 {
    73  		return false, FarawayFuture
    74  	}
    75  
    76  	// malformed ip address is banned
    77  	ip := net.ParseIP(addr)
    78  	if ip == nil {
    79  		return true, FarawayFuture
    80  	}
    81  
    82  	// bps are automatically allowed
    83  	if lm.prm.GetRole(pid) == p2pcommon.BlockProducer {
    84  		return false, FarawayFuture
    85  	}
    86  
    87  	// finally check peer is in list
    88  	for _, ent := range lm.entries {
    89  		if ent.Contains(ip, pid) {
    90  			return false, FarawayFuture
    91  		}
    92  	}
    93  	return true, FarawayFuture
    94  }
    95  
    96  func (lm *listManagerImpl) RefineList() {
    97  	if lm.publicNet {
    98  		lm.logger.Info().Msg("network is public, apply default policy instead (allow all)")
    99  		lm.entries = make([]types.WhiteListEntry, 0)
   100  		lm.enabled = false
   101  		return
   102  	}
   103  
   104  	wl, err := lm.chainAcc.GetEnterpriseConfig(enterprise.P2PWhite)
   105  	if err != nil {
   106  		lm.logger.Info().Msg("error while getting whitelist config. apply default policy instead (allow all)")
   107  		//ent, _ := ParseListEntry(":")
   108  		//lm.entries = append(lm.entries, ent)
   109  		lm.entries = make([]types.WhiteListEntry, 0)
   110  		lm.enabled = false
   111  		return
   112  	}
   113  	lm.enabled = wl.GetOn()
   114  	if !wl.GetOn() {
   115  		lm.logger.Debug().Msg("whitelist conf is disabled. apply default policy instead (allow all)")
   116  		lm.entries = make([]types.WhiteListEntry, 0)
   117  	} else if len(wl.Values) == 0 {
   118  		lm.logger.Debug().Msg("no whitelist found. apply default policy instead (allow all)")
   119  		//ent, _ := ParseListEntry(":")
   120  		//lm.entries = append(lm.entries, ent)
   121  		lm.entries = make([]types.WhiteListEntry, 0)
   122  	} else {
   123  		entries := make([]types.WhiteListEntry, 0, len(wl.Values))
   124  		for _, v := range wl.Values {
   125  			ent, err := types.ParseListEntry(v)
   126  			if err != nil {
   127  				panic("invalid whitelist entry " + v)
   128  			}
   129  			entries = append(entries, ent)
   130  		}
   131  		lm.entries = entries
   132  		lm.logger.Debug().Str("entries", strings.Join(wl.Values, " , ")).Msg("loaded whitelist entries")
   133  	}
   134  
   135  }
   136  
   137  func (lm *listManagerImpl) Summary() map[string]interface{} {
   138  	// There can be a little error
   139  	sum := make(map[string]interface{})
   140  	entries := make([]string, 0, len(lm.entries))
   141  	for _, e := range lm.entries {
   142  		entries = append(entries, e.String())
   143  	}
   144  	sum["whitelist"] = entries
   145  	sum["whitelist_on"] = lm.enabled
   146  
   147  	return sum
   148  }