github.com/metacubex/mihomo@v1.18.5/listener/http/server.go (about)

     1  package http
     2  
     3  import (
     4  	"net"
     5  
     6  	"github.com/metacubex/mihomo/adapter/inbound"
     7  	"github.com/metacubex/mihomo/common/lru"
     8  	C "github.com/metacubex/mihomo/constant"
     9  	"github.com/metacubex/mihomo/constant/features"
    10  )
    11  
    12  type Listener struct {
    13  	listener net.Listener
    14  	addr     string
    15  	closed   bool
    16  }
    17  
    18  // RawAddress implements C.Listener
    19  func (l *Listener) RawAddress() string {
    20  	return l.addr
    21  }
    22  
    23  // Address implements C.Listener
    24  func (l *Listener) Address() string {
    25  	return l.listener.Addr().String()
    26  }
    27  
    28  // Close implements C.Listener
    29  func (l *Listener) Close() error {
    30  	l.closed = true
    31  	return l.listener.Close()
    32  }
    33  
    34  func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) {
    35  	return NewWithAuthenticate(addr, tunnel, true, additions...)
    36  }
    37  
    38  func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additions ...inbound.Addition) (*Listener, error) {
    39  	isDefault := false
    40  	if len(additions) == 0 {
    41  		isDefault = true
    42  		additions = []inbound.Addition{
    43  			inbound.WithInName("DEFAULT-HTTP"),
    44  			inbound.WithSpecialRules(""),
    45  		}
    46  	}
    47  	l, err := inbound.Listen("tcp", addr)
    48  
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	var c *lru.LruCache[string, bool]
    54  	if authenticate {
    55  		c = lru.New[string, bool](lru.WithAge[string, bool](30))
    56  	}
    57  
    58  	hl := &Listener{
    59  		listener: l,
    60  		addr:     addr,
    61  	}
    62  	go func() {
    63  		for {
    64  			conn, err := hl.listener.Accept()
    65  			if err != nil {
    66  				if hl.closed {
    67  					break
    68  				}
    69  				continue
    70  			}
    71  			if features.CMFA {
    72  				if t, ok := conn.(*net.TCPConn); ok {
    73  					t.SetKeepAlive(false)
    74  				}
    75  			}
    76  			if isDefault { // only apply on default listener
    77  				if !inbound.IsRemoteAddrDisAllowed(conn.RemoteAddr()) {
    78  					_ = conn.Close()
    79  					continue
    80  				}
    81  			}
    82  			go HandleConn(conn, tunnel, c, additions...)
    83  		}
    84  	}()
    85  
    86  	return hl, nil
    87  }