mirror of
https://github.com/ICKelin/opennotr.git
synced 2025-09-26 20:01:13 +08:00
feature: reply proxy info to client
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
serverAddr: "demo.notr.tech:10100"
|
||||
key: "client server exchange key"
|
||||
key: "http://www.notr.tech"
|
||||
forwards:
|
||||
- protocol: tcp
|
||||
ports:
|
||||
2221: 2222
|
||||
0: 2222
|
||||
|
||||
- protocol: udp
|
||||
ports:
|
||||
531: 53
|
||||
0: 53
|
||||
|
||||
- protocol: http
|
||||
ports:
|
||||
@@ -20,9 +20,4 @@ forwards:
|
||||
- protocol: h2c
|
||||
ports:
|
||||
0: 50052
|
||||
|
||||
- protocol: dummy
|
||||
ports:
|
||||
0: 0
|
||||
rawConfig:
|
||||
"this is a test config pass to dummy plugin"
|
||||
|
@@ -21,7 +21,7 @@ type C2SHeartbeat struct{}
|
||||
type C2SAuth struct {
|
||||
Key string `json:"key" yaml:"key"`
|
||||
Domain string `json:"domain" yaml:"domain"`
|
||||
Forward []ForwardItem `json:"forwards" yaml:"forwards"`
|
||||
Forward []ForwardItem `json:"forwards" yaml:"forwards"` // request forwards, not real, it depends on opennotrd
|
||||
}
|
||||
|
||||
type ForwardItem struct {
|
||||
@@ -43,8 +43,15 @@ type ForwardItem struct {
|
||||
}
|
||||
|
||||
type S2CAuth struct {
|
||||
Domain string `json:"domain"` // 分配域名
|
||||
Vip string `json:"vip"` // 分配虚拟ip地址
|
||||
Domain string `json:"domain"` // uniq domain for opennotr
|
||||
Vip string `json:"vip"` // vip for opennotr
|
||||
ProxyInfos []*ProxyTuple `json:"proxyInfos"` // real proxy table
|
||||
}
|
||||
|
||||
type ProxyTuple struct {
|
||||
Protocol string
|
||||
FromPort string
|
||||
ToPort string
|
||||
}
|
||||
|
||||
type ProxyProtocol struct {
|
||||
|
@@ -75,6 +75,13 @@ func (c *Client) Run() {
|
||||
log.Println("connect success")
|
||||
log.Println("vhost:", auth.Vip)
|
||||
log.Println("domain:", auth.Domain)
|
||||
for _, item := range auth.ProxyInfos {
|
||||
fromaddr := fmt.Sprintf("%s:%s", auth.Domain, item.FromPort)
|
||||
if len(item.FromPort) == 0 {
|
||||
fromaddr = auth.Domain
|
||||
}
|
||||
log.Printf("%s://%s => 127.0.0.1:%s\n", item.Protocol, fromaddr, item.ToPort)
|
||||
}
|
||||
|
||||
mux, err := smux.Client(conn, nil)
|
||||
if err != nil {
|
||||
|
@@ -98,17 +98,6 @@ func (s *Server) onConn(conn net.Conn) {
|
||||
return
|
||||
}
|
||||
|
||||
reply := &proto.S2CAuth{
|
||||
Vip: vip,
|
||||
Domain: auth.Domain,
|
||||
}
|
||||
|
||||
err = proto.WriteJSON(conn, proto.CmdAuth, reply)
|
||||
if err != nil {
|
||||
logs.Error("write json fail: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// dynamic dns, write domain=>ip map to etcd
|
||||
// coredns will read records from etcd and reply to dns client
|
||||
if s.resolver != nil {
|
||||
@@ -128,6 +117,7 @@ func (s *Server) onConn(conn net.Conn) {
|
||||
// 2. for to address, we use $vip:$localPort
|
||||
// the vip is the virtual lan ip address
|
||||
// Domain is only use for restyproxy
|
||||
proxyInfos := make([]*proto.ProxyTuple, 0)
|
||||
for _, forward := range auth.Forward {
|
||||
for publicPort, localPort := range forward.Ports {
|
||||
item := &plugin.PluginMeta{
|
||||
@@ -139,15 +129,32 @@ func (s *Server) onConn(conn net.Conn) {
|
||||
Ctx: forward.RawConfig,
|
||||
}
|
||||
|
||||
err = s.pluginMgr.AddProxy(item)
|
||||
p, err := s.pluginMgr.AddProxy(item)
|
||||
if err != nil {
|
||||
logs.Error("add proxy fail: %v", err)
|
||||
return
|
||||
}
|
||||
proxyInfos = append(proxyInfos, &proto.ProxyTuple{
|
||||
Protocol: forward.Protocol,
|
||||
FromPort: p.FromPort,
|
||||
ToPort: p.ToPort,
|
||||
})
|
||||
defer s.pluginMgr.DelProxy(item)
|
||||
}
|
||||
}
|
||||
|
||||
reply := &proto.S2CAuth{
|
||||
Vip: vip,
|
||||
Domain: auth.Domain,
|
||||
ProxyInfos: proxyInfos,
|
||||
}
|
||||
|
||||
err = proto.WriteJSON(conn, proto.CmdAuth, reply)
|
||||
if err != nil {
|
||||
logs.Error("write json fail: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
mux, err := smux.Server(conn, nil)
|
||||
if err != nil {
|
||||
logs.Error("smux server fail:%v", err)
|
||||
|
@@ -17,9 +17,9 @@ func (d *DummyPlugin) Setup(cfg json.RawMessage) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DummyPlugin) RunProxy(meta *plugin.PluginMeta) error {
|
||||
func (d *DummyPlugin) RunProxy(meta *plugin.PluginMeta) (*plugin.ProxyTuple, error) {
|
||||
logs.Info("dummy plugin client config: %v", meta.Ctx)
|
||||
return nil
|
||||
return &plugin.ProxyTuple{}, nil
|
||||
}
|
||||
|
||||
func (d *DummyPlugin) StopProxy(meta *plugin.PluginMeta) {}
|
||||
|
@@ -13,6 +13,13 @@ var pluginMgr = &PluginManager{
|
||||
plugins: make(map[string]IPlugin),
|
||||
}
|
||||
|
||||
// ProxyTuple defineds plugins real proxy address
|
||||
type ProxyTuple struct {
|
||||
Protocol string
|
||||
FromPort string
|
||||
ToPort string
|
||||
}
|
||||
|
||||
// PluginMeta defineds data that the plugins needs
|
||||
// these members are filled by server.go
|
||||
type PluginMeta struct {
|
||||
@@ -58,7 +65,7 @@ type IPlugin interface {
|
||||
StopProxy(item *PluginMeta)
|
||||
|
||||
// Run a proxy, it may be called by client's connection established
|
||||
RunProxy(item *PluginMeta) error
|
||||
RunProxy(item *PluginMeta) (*ProxyTuple, error)
|
||||
}
|
||||
|
||||
type PluginManager struct {
|
||||
@@ -103,26 +110,26 @@ func Setup(plugins map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PluginManager) AddProxy(item *PluginMeta) error {
|
||||
func (p *PluginManager) AddProxy(item *PluginMeta) (*ProxyTuple, 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)
|
||||
return nil, fmt.Errorf("port %s is in used", key)
|
||||
}
|
||||
|
||||
plug, ok := p.plugins[item.Protocol]
|
||||
if !ok {
|
||||
return fmt.Errorf("proxy %s not register", item.Protocol)
|
||||
return nil, fmt.Errorf("proxy %s not register", item.Protocol)
|
||||
}
|
||||
|
||||
err := plug.RunProxy(item)
|
||||
tuple, err := plug.RunProxy(item)
|
||||
if err != nil {
|
||||
logs.Error("run proxy fail: %v", err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
p.routes[key] = item
|
||||
return nil
|
||||
return tuple, nil
|
||||
}
|
||||
|
||||
func (p *PluginManager) DelProxy(item *PluginMeta) {
|
||||
|
@@ -50,10 +50,10 @@ func (p *RestyProxy) StopProxy(item *plugin.PluginMeta) {
|
||||
p.sendDeleteReq(item.Domain, item.Protocol)
|
||||
}
|
||||
|
||||
func (p *RestyProxy) RunProxy(item *plugin.PluginMeta) error {
|
||||
func (p *RestyProxy) RunProxy(item *plugin.PluginMeta) (*plugin.ProxyTuple, error) {
|
||||
vip, port, err := net.SplitHostPort(item.To)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &AddUpstreamBody{
|
||||
@@ -64,7 +64,12 @@ func (p *RestyProxy) RunProxy(item *plugin.PluginMeta) error {
|
||||
}
|
||||
|
||||
go p.sendPostReq(req)
|
||||
return nil
|
||||
|
||||
_, toPort, _ := net.SplitHostPort(item.To)
|
||||
return &plugin.ProxyTuple{
|
||||
Protocol: item.Protocol,
|
||||
ToPort: toPort,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *RestyProxy) sendPostReq(body interface{}) {
|
||||
|
@@ -26,11 +26,13 @@ func (t *TCPProxy) StopProxy(item *plugin.PluginMeta) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TCPProxy) RunProxy(item *plugin.PluginMeta) error {
|
||||
// RunProxy runs a tcp server and proxy to item.To
|
||||
// RunProxy may change item.From address to the real listenner address
|
||||
func (t *TCPProxy) RunProxy(item *plugin.PluginMeta) (*plugin.ProxyTuple, error) {
|
||||
from, to := item.From, item.To
|
||||
lis, err := net.Listen("tcp", from)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fin := make(chan struct{})
|
||||
@@ -73,7 +75,14 @@ func (t *TCPProxy) RunProxy(item *plugin.PluginMeta) error {
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
_, fromPort, _ := net.SplitHostPort(lis.Addr().String())
|
||||
_, toPort, _ := net.SplitHostPort(item.To)
|
||||
|
||||
return &plugin.ProxyTuple{
|
||||
Protocol: item.Protocol,
|
||||
FromPort: fromPort,
|
||||
ToPort: toPort,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *TCPProxy) doProxy(conn net.Conn, to string) {
|
||||
|
@@ -48,20 +48,28 @@ func (p *UDPProxy) StopProxy(item *plugin.PluginMeta) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *UDPProxy) RunProxy(item *plugin.PluginMeta) error {
|
||||
func (p *UDPProxy) RunProxy(item *plugin.PluginMeta) (*plugin.ProxyTuple, error) {
|
||||
from := item.From
|
||||
laddr, err := net.ResolveUDPAddr("udp", from)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lis, err := net.ListenUDP("udp", laddr)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go p.doProxy(lis, item)
|
||||
return nil
|
||||
|
||||
_, fromPort, _ := net.SplitHostPort(lis.LocalAddr().String())
|
||||
_, toPort, _ := net.SplitHostPort(item.To)
|
||||
|
||||
return &plugin.ProxyTuple{
|
||||
Protocol: item.Protocol,
|
||||
FromPort: fromPort,
|
||||
ToPort: toPort,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *UDPProxy) doProxy(lis *net.UDPConn, item *plugin.PluginMeta) {
|
||||
|
Reference in New Issue
Block a user