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 }