feat: add linsters

This commit is contained in:
Skyxim
2022-12-04 13:37:14 +08:00
parent ba884c29bd
commit 4f75201a98
49 changed files with 1018 additions and 306 deletions

66
listener/inbound/base.go Normal file
View File

@ -0,0 +1,66 @@
package inbound
import (
"net"
"net/netip"
"strconv"
C "github.com/Dreamacro/clash/constant"
)
type Base struct {
name string
preferRulesName string
listenAddr netip.Addr
port int
}
func NewBase(options *BaseOption) (*Base, error) {
if options.Listen == "" {
options.Listen = "0.0.0.0"
}
addr, err := netip.ParseAddr(options.Listen)
if err != nil {
return nil, err
}
return &Base{
name: options.Name,
listenAddr: addr,
preferRulesName: options.PreferRulesName,
port: options.Port,
}, nil
}
// Address implements constant.NewListener
func (b *Base) Address() string {
return b.RawAddress()
}
// Close implements constant.NewListener
func (*Base) Close() error {
return nil
}
// Name implements constant.NewListener
func (b *Base) Name() string {
return b.name
}
// RawAddress implements constant.NewListener
func (b *Base) RawAddress() string {
return net.JoinHostPort(b.listenAddr.String(), strconv.Itoa(int(b.port)))
}
// ReCreate implements constant.NewListener
func (*Base) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error {
return nil
}
type BaseOption struct {
Name string `inbound:"name"`
Listen string `inbound:"listen,omitempty"`
Port int `inbound:"port"`
PreferRulesName string `inbound:"rule,omitempty"`
}
var _ C.NewListener = (*Base)(nil)

52
listener/inbound/http.go Normal file
View File

@ -0,0 +1,52 @@
package inbound
import (
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/http"
"github.com/Dreamacro/clash/log"
)
type HTTPOption struct {
BaseOption
}
type HTTP struct {
*Base
l *http.Listener
}
func NewHTTP(options *HTTPOption) (*HTTP, error) {
base, err := NewBase(&options.BaseOption)
if err != nil {
return nil, err
}
return &HTTP{
Base: base,
}, nil
}
// Address implements constant.NewListener
func (h *HTTP) Address() string {
return h.l.Address()
}
// ReCreate implements constant.NewListener
func (h *HTTP) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error {
var err error
_ = h.Close()
h.l, err = http.NewWithInfos(h.RawAddress(), h.name, h.preferRulesName, tcpIn)
if err != nil {
return err
}
log.Infoln("HTTP[%s] proxy listening at: %s", h.Name(), h.Address())
return nil
}
// Close implements constant.NewListener
func (h *HTTP) Close() error {
if h.l != nil {
return h.l.Close()
}
return nil
}
var _ C.NewListener = (*HTTP)(nil)

79
listener/inbound/mixed.go Normal file
View File

@ -0,0 +1,79 @@
package inbound
import (
"fmt"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/listener/mixed"
"github.com/Dreamacro/clash/listener/socks"
)
type MixedOption struct {
BaseOption
UDP *bool `inbound:"udp,omitempty"`
}
type Mixed struct {
*Base
l *mixed.Listener
lUDP *socks.UDPListener
udp bool
}
func NewMixed(options *MixedOption) (*Mixed, error) {
base, err := NewBase(&options.BaseOption)
if err != nil {
return nil, err
}
return &Mixed{
Base: base,
udp: options.UDP == nil || *options.UDP,
}, nil
}
// Address implements constant.NewListener
func (m *Mixed) Address() string {
return m.l.Address()
}
// ReCreate implements constant.NewListener
func (m *Mixed) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error {
var err error
_ = m.Close()
m.l, err = mixed.NewWithInfos(m.RawAddress(), m.name, m.preferRulesName, tcpIn)
if err != nil {
return err
}
if m.udp {
m.lUDP, err = socks.NewUDPWithInfos(m.Address(), m.name, m.preferRulesName, udpIn)
if err != nil {
return err
}
}
log.Infoln("Mixed(http+socks)[%s] proxy listening at: %s", m.Name(), m.Address())
return nil
}
// Close implements constant.NewListener
func (m *Mixed) Close() error {
var err error
if m.l != nil {
if tcpErr := m.l.Close(); tcpErr != nil {
err = tcpErr
}
}
if m.udp && m.lUDP != nil {
if udpErr := m.lUDP.Close(); udpErr != nil {
if err == nil {
err = udpErr
} else {
return fmt.Errorf("close tcp err: %s, close udp err: %s", err.Error(), udpErr.Error())
}
}
}
return err
}
var _ C.NewListener = (*Mixed)(nil)

53
listener/inbound/redir.go Normal file
View File

@ -0,0 +1,53 @@
package inbound
import (
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/redir"
"github.com/Dreamacro/clash/log"
)
type RedirOption struct {
BaseOption
}
type Redir struct {
*Base
l *redir.Listener
}
func NewRedir(options *RedirOption) (*Redir, error) {
base, err := NewBase(&options.BaseOption)
if err != nil {
return nil, err
}
return &Redir{
Base: base,
}, nil
}
// Address implements constant.NewListener
func (r *Redir) Address() string {
return r.l.Address()
}
// ReCreate implements constant.NewListener
func (r *Redir) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error {
var err error
_ = r.Close()
r.l, err = redir.NewWithInfos(r.Address(), r.name, r.preferRulesName, tcpIn)
if err != nil {
return err
}
log.Infoln("Redir[%s] proxy listening at: %s", r.Name(), r.Address())
return nil
}
// Close implements constant.NewListener
func (r *Redir) Close() error {
if r.l != nil {
r.l.Close()
}
return nil
}
var _ C.NewListener = (*Redir)(nil)

81
listener/inbound/socks.go Normal file
View File

@ -0,0 +1,81 @@
package inbound
import (
"fmt"
"sync"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/socks"
"github.com/Dreamacro/clash/log"
)
type SocksOption struct {
BaseOption
UDP *bool `inbound:"udp,omitempty"`
}
type Socks struct {
*Base
mux sync.Mutex
udp bool
stl *socks.Listener
sul *socks.UDPListener
}
func NewSocks(options *SocksOption) (*Socks, error) {
base, err := NewBase(&options.BaseOption)
if err != nil {
return nil, err
}
return &Socks{
Base: base,
udp: options.UDP == nil || *options.UDP,
}, nil
}
// Close implements constant.NewListener
func (s *Socks) Close() error {
var err error
if s.stl != nil {
if tcpErr := s.stl.Close(); tcpErr != nil {
err = tcpErr
}
}
if s.udp && s.sul != nil {
if udpErr := s.sul.Close(); udpErr != nil {
if err == nil {
err = udpErr
} else {
return fmt.Errorf("close tcp err: %s, close udp err: %s", err.Error(), udpErr.Error())
}
}
}
return err
}
// Address implements constant.NewListener
func (s *Socks) Address() string {
return s.stl.Address()
}
// ReCreate implements constant.NewListener
func (s *Socks) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error {
s.mux.Lock()
defer s.mux.Unlock()
var err error
_ = s.Close()
if s.stl, err = socks.NewWithInfos(s.RawAddress(), s.name, s.preferRulesName, tcpIn); err != nil {
return err
}
if s.udp {
if s.sul, err = socks.NewUDPWithInfos(s.RawAddress(), s.name, s.preferRulesName, udpIn); err != nil {
return err
}
}
log.Infoln("SOCKS[%s] proxy listening at: %s", s.Name(), s.Address())
return nil
}
var _ C.NewListener = (*Socks)(nil)

View File

@ -0,0 +1,84 @@
package inbound
import (
"fmt"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/tproxy"
"github.com/Dreamacro/clash/log"
)
type TProxyOption struct {
BaseOption
UDP *bool `inbound:"udp,omitempty"`
}
type TProxy struct {
*Base
lUDP *tproxy.UDPListener
lTCP *tproxy.Listener
udp bool
}
func NewTProxy(options *TProxyOption) (*TProxy, error) {
base, err := NewBase(&options.BaseOption)
if err != nil {
return nil, err
}
return &TProxy{
Base: base,
udp: options.UDP == nil || *options.UDP,
}, nil
}
// Address implements constant.NewListener
func (t *TProxy) Address() string {
return t.lTCP.Address()
}
// ReCreate implements constant.NewListener
func (t *TProxy) ReCreate(tcpIn chan<- C.ConnContext, udpIn chan<- *C.PacketAdapter) error {
var err error
_ = t.Close()
t.lTCP, err = tproxy.NewWithInfos(t.RawAddress(), t.name, t.preferRulesName, tcpIn)
if err != nil {
return err
}
if t.udp {
if t.lUDP != nil {
t.lUDP, err = tproxy.NewUDPWithInfos(t.Address(), t.name, t.preferRulesName, udpIn)
if err != nil {
return err
}
}
}
log.Infoln("TProxy[%s] proxy listening at: %s", t.Name(), t.Address())
return nil
}
// Close implements constant.NewListener
func (t *TProxy) Close() error {
var tcpErr error
var udpErr error
if t.lTCP != nil {
tcpErr = t.lTCP.Close()
}
if t.lUDP != nil {
udpErr = t.lUDP.Close()
}
if tcpErr != nil && udpErr != nil {
return fmt.Errorf("tcp close err: %s and udp close err: %s", tcpErr, udpErr)
}
if tcpErr != nil {
return tcpErr
}
if udpErr != nil {
return udpErr
}
return nil
}
var _ C.NewListener = (*TProxy)(nil)