123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- package file
- import (
- "strings"
- "sync"
- "sync/atomic"
- "time"
- "ehang.io/nps/lib/rate"
- "github.com/pkg/errors"
- )
- type Flow struct {
- ExportFlow int64
- InletFlow int64
- FlowLimit int64
- sync.RWMutex
- }
- func (s *Flow) Add(in, out int64) {
- s.Lock()
- defer s.Unlock()
- s.InletFlow += int64(in)
- s.ExportFlow += int64(out)
- }
- type Config struct {
- U string
- P string
- Compress bool
- Crypt bool
- }
- type Client struct {
- Cnf *Config
- Id int //id
- VerifyKey string //verify key
- Addr string //the ip of client
- Remark string //remark
- Status bool //is allow connect
- IsConnect bool //is the client connect
- RateLimit int //rate /kb
- Flow *Flow //flow setting
- Rate *rate.Rate //rate limit
- NoStore bool //no store to file
- NoDisplay bool //no display on web
- MaxConn int //the max connection num of client allow
- NowConn int32 //the connection num of now
- WebUserName string //the username of web login
- WebPassword string //the password of web login
- ConfigConnAllow bool //is allow connected by config file
- MaxTunnelNum int
- Version string
- sync.RWMutex
- }
- func NewClient(vKey string, noStore bool, noDisplay bool) *Client {
- return &Client{
- Cnf: new(Config),
- Id: 0,
- VerifyKey: vKey,
- Addr: "",
- Remark: "",
- Status: true,
- IsConnect: false,
- RateLimit: 0,
- Flow: new(Flow),
- Rate: nil,
- NoStore: noStore,
- RWMutex: sync.RWMutex{},
- NoDisplay: noDisplay,
- }
- }
- func (s *Client) CutConn() {
- atomic.AddInt32(&s.NowConn, 1)
- }
- func (s *Client) AddConn() {
- atomic.AddInt32(&s.NowConn, -1)
- }
- func (s *Client) GetConn() bool {
- if s.MaxConn == 0 || int(s.NowConn) < s.MaxConn {
- s.CutConn()
- return true
- }
- return false
- }
- func (s *Client) HasTunnel(t *Tunnel) (exist bool) {
- GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
- v := value.(*Tunnel)
- if v.Client.Id == s.Id && v.Port == t.Port && t.Port != 0 {
- exist = true
- return false
- }
- return true
- })
- return
- }
- func (s *Client) GetTunnelNum() (num int) {
- GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
- v := value.(*Tunnel)
- if v.Client.Id == s.Id {
- num++
- }
- return true
- })
- return
- }
- func (s *Client) HasHost(h *Host) bool {
- var has bool
- GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
- v := value.(*Host)
- if v.Client.Id == s.Id && v.Host == h.Host && h.Location == v.Location {
- has = true
- return false
- }
- return true
- })
- return has
- }
- type Tunnel struct {
- Id int
- Port int
- ServerIp string
- Mode string
- Status bool
- RunStatus bool
- Client *Client
- Ports string
- Flow *Flow
- Password string
- Remark string
- TargetAddr string
- NoStore bool
- LocalPath string
- StripPre string
- Target *Target
- MultiAccount *MultiAccount
- Health
- sync.RWMutex
- }
- type Health struct {
- HealthCheckTimeout int
- HealthMaxFail int
- HealthCheckInterval int
- HealthNextTime time.Time
- HealthMap map[string]int
- HttpHealthUrl string
- HealthRemoveArr []string
- HealthCheckType string
- HealthCheckTarget string
- sync.RWMutex
- }
- type Host struct {
- Id int
- Host string //host
- HeaderChange string //header change
- HostChange string //host change
- Location string //url router
- Remark string //remark
- Scheme string //http https all
- CertFilePath string
- KeyFilePath string
- NoStore bool
- IsClose bool
- Flow *Flow
- Client *Client
- Target *Target //目标
- Health `json:"-"`
- sync.RWMutex
- }
- type Target struct {
- nowIndex int
- TargetStr string
- TargetArr []string
- LocalProxy bool
- sync.RWMutex
- }
- type MultiAccount struct {
- AccountMap map[string]string // multi account and pwd
- }
- func (s *Target) GetRandomTarget() (string, error) {
- if s.TargetArr == nil {
- s.TargetArr = strings.Split(s.TargetStr, "\n")
- }
- if len(s.TargetArr) == 1 {
- return s.TargetArr[0], nil
- }
- if len(s.TargetArr) == 0 {
- return "", errors.New("all inward-bending targets are offline")
- }
- s.Lock()
- defer s.Unlock()
- if s.nowIndex >= len(s.TargetArr)-1 {
- s.nowIndex = -1
- }
- s.nowIndex++
- return s.TargetArr[s.nowIndex], nil
- }
|