feat: add linsters
This commit is contained in:
66
listener/inbound/base.go
Normal file
66
listener/inbound/base.go
Normal 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
52
listener/inbound/http.go
Normal 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
79
listener/inbound/mixed.go
Normal 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
53
listener/inbound/redir.go
Normal 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
81
listener/inbound/socks.go
Normal 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)
|
84
listener/inbound/tproxy.go
Normal file
84
listener/inbound/tproxy.go
Normal 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)
|
Reference in New Issue
Block a user