mirror of
https://github.com/ICKelin/opennotr.git
synced 2025-10-23 15:53:13 +08:00
112 lines
2.3 KiB
Go
112 lines
2.3 KiB
Go
package plugin
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/ICKelin/opennotr/pkg/logs"
|
|
)
|
|
|
|
var stream = &Stream{
|
|
routes: make(map[string]*ProxyItem),
|
|
proxier: make(map[string]Proxier),
|
|
}
|
|
|
|
type ProxyItem struct {
|
|
Protocol string
|
|
From string
|
|
To string
|
|
Host string // host for restyproxy
|
|
Ctx interface{} // data pass to proxier
|
|
RecycleSignal chan struct{}
|
|
}
|
|
|
|
func (item *ProxyItem) identify() string {
|
|
return fmt.Sprintf("%s:%s:%s:%s", item.Protocol, item.From, item.To, item.Host)
|
|
}
|
|
|
|
// Proxier defines stream proxy API
|
|
type Proxier interface {
|
|
Setup(json.RawMessage) error
|
|
StopProxy(item *ProxyItem)
|
|
RunProxy(item *ProxyItem) error
|
|
}
|
|
|
|
type Stream struct {
|
|
mu sync.Mutex
|
|
|
|
// routes stores proxier of localAddress
|
|
// key: proxyItem.identify()
|
|
// value: proxyItem
|
|
routes map[string]*ProxyItem
|
|
|
|
// proxier stores proxier info of each registerd proxier
|
|
// by call RegisterProxier function.
|
|
// key: protocol, eg: tcp, udp
|
|
// value: proxy implement
|
|
proxier map[string]Proxier
|
|
}
|
|
|
|
func DefaultStream() *Stream {
|
|
return stream
|
|
}
|
|
|
|
func RegisterProxier(protocol string, proxier Proxier) {
|
|
stream.proxier[protocol] = proxier
|
|
}
|
|
|
|
func Setup(plugins map[string]string) error {
|
|
for protocol, cfg := range plugins {
|
|
logs.Info("setup for %s with configuration:\n%s", protocol, cfg)
|
|
proxier, ok := stream.proxier[protocol]
|
|
if !ok {
|
|
logs.Error("protocol %s not register", protocol)
|
|
return fmt.Errorf("protocol %s not register", protocol)
|
|
}
|
|
|
|
err := proxier.Setup([]byte(cfg))
|
|
if err != nil {
|
|
logs.Error("setup protocol %s fail: %v", protocol, err)
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p *Stream) AddProxy(item *ProxyItem) error {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
key := item.identify()
|
|
if _, ok := p.routes[key]; ok {
|
|
return fmt.Errorf("port %s is in used", key)
|
|
}
|
|
|
|
proxier, ok := p.proxier[item.Protocol]
|
|
if !ok {
|
|
return fmt.Errorf("proxy %s not register", item.Protocol)
|
|
}
|
|
|
|
err := proxier.RunProxy(item)
|
|
if err != nil {
|
|
logs.Error("run proxy fail: %v", err)
|
|
return err
|
|
}
|
|
p.routes[key] = item
|
|
return nil
|
|
}
|
|
|
|
func (p *Stream) DelProxy(item *ProxyItem) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
key := item.identify()
|
|
|
|
proxier, ok := p.proxier[item.Protocol]
|
|
if ok {
|
|
proxier.StopProxy(item)
|
|
}
|
|
|
|
delete(p.routes, key)
|
|
}
|