manager.go 5.7 KB
Newer Older
F
fatedier 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// Copyright 2019 fatedier, fatedier@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package plugin

import (
	"context"
	"errors"
	"fmt"

F
fatedier 已提交
22 23
	"github.com/fatedier/frp/pkg/util/util"
	"github.com/fatedier/frp/pkg/util/xlog"
F
fatedier 已提交
24 25 26
)

type Manager struct {
27 28 29 30
	loginPlugins       []Plugin
	newProxyPlugins    []Plugin
	pingPlugins        []Plugin
	newWorkConnPlugins []Plugin
31
	newUserConnPlugins []Plugin
F
fatedier 已提交
32 33 34 35
}

func NewManager() *Manager {
	return &Manager{
36 37 38 39
		loginPlugins:       make([]Plugin, 0),
		newProxyPlugins:    make([]Plugin, 0),
		pingPlugins:        make([]Plugin, 0),
		newWorkConnPlugins: make([]Plugin, 0),
40
		newUserConnPlugins: make([]Plugin, 0),
F
fatedier 已提交
41 42 43 44 45 46 47 48 49 50
	}
}

func (m *Manager) Register(p Plugin) {
	if p.IsSupport(OpLogin) {
		m.loginPlugins = append(m.loginPlugins, p)
	}
	if p.IsSupport(OpNewProxy) {
		m.newProxyPlugins = append(m.newProxyPlugins, p)
	}
51 52 53 54
	if p.IsSupport(OpPing) {
		m.pingPlugins = append(m.pingPlugins, p)
	}
	if p.IsSupport(OpNewWorkConn) {
T
Tank 已提交
55
		m.newWorkConnPlugins = append(m.newWorkConnPlugins, p)
56
	}
57 58 59
	if p.IsSupport(OpNewUserConn) {
		m.newUserConnPlugins = append(m.newUserConnPlugins, p)
	}
F
fatedier 已提交
60 61 62
}

func (m *Manager) Login(content *LoginContent) (*LoginContent, error) {
63 64 65 66
	if len(m.loginPlugins) == 0 {
		return content, nil
	}

F
fatedier 已提交
67 68 69 70 71 72 73 74
	var (
		res = &Response{
			Reject:   false,
			Unchange: true,
		}
		retContent interface{}
		err        error
	)
F
fatedier 已提交
75
	reqid, _ := util.RandID()
F
fatedier 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
	xl := xlog.New().AppendPrefix("reqid: " + reqid)
	ctx := xlog.NewContext(context.Background(), xl)
	ctx = NewReqidContext(ctx, reqid)

	for _, p := range m.loginPlugins {
		res, retContent, err = p.Handle(ctx, OpLogin, *content)
		if err != nil {
			xl.Warn("send Login request to plugin [%s] error: %v", p.Name(), err)
			return nil, errors.New("send Login request to plugin error")
		}
		if res.Reject {
			return nil, fmt.Errorf("%s", res.RejectReason)
		}
		if !res.Unchange {
			content = retContent.(*LoginContent)
		}
	}
	return content, nil
}

func (m *Manager) NewProxy(content *NewProxyContent) (*NewProxyContent, error) {
97 98 99 100
	if len(m.newProxyPlugins) == 0 {
		return content, nil
	}

F
fatedier 已提交
101 102 103 104 105 106 107 108
	var (
		res = &Response{
			Reject:   false,
			Unchange: true,
		}
		retContent interface{}
		err        error
	)
F
fatedier 已提交
109
	reqid, _ := util.RandID()
F
fatedier 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	xl := xlog.New().AppendPrefix("reqid: " + reqid)
	ctx := xlog.NewContext(context.Background(), xl)
	ctx = NewReqidContext(ctx, reqid)

	for _, p := range m.newProxyPlugins {
		res, retContent, err = p.Handle(ctx, OpNewProxy, *content)
		if err != nil {
			xl.Warn("send NewProxy request to plugin [%s] error: %v", p.Name(), err)
			return nil, errors.New("send NewProxy request to plugin error")
		}
		if res.Reject {
			return nil, fmt.Errorf("%s", res.RejectReason)
		}
		if !res.Unchange {
			content = retContent.(*NewProxyContent)
		}
	}
	return content, nil
}
129 130

func (m *Manager) Ping(content *PingContent) (*PingContent, error) {
131 132 133 134
	if len(m.pingPlugins) == 0 {
		return content, nil
	}

135 136 137 138 139 140 141 142
	var (
		res = &Response{
			Reject:   false,
			Unchange: true,
		}
		retContent interface{}
		err        error
	)
F
fatedier 已提交
143
	reqid, _ := util.RandID()
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
	xl := xlog.New().AppendPrefix("reqid: " + reqid)
	ctx := xlog.NewContext(context.Background(), xl)
	ctx = NewReqidContext(ctx, reqid)

	for _, p := range m.pingPlugins {
		res, retContent, err = p.Handle(ctx, OpPing, *content)
		if err != nil {
			xl.Warn("send Ping request to plugin [%s] error: %v", p.Name(), err)
			return nil, errors.New("send Ping request to plugin error")
		}
		if res.Reject {
			return nil, fmt.Errorf("%s", res.RejectReason)
		}
		if !res.Unchange {
			content = retContent.(*PingContent)
		}
	}
	return content, nil
}

func (m *Manager) NewWorkConn(content *NewWorkConnContent) (*NewWorkConnContent, error) {
165 166 167 168
	if len(m.newWorkConnPlugins) == 0 {
		return content, nil
	}

169 170 171 172 173 174 175 176
	var (
		res = &Response{
			Reject:   false,
			Unchange: true,
		}
		retContent interface{}
		err        error
	)
F
fatedier 已提交
177
	reqid, _ := util.RandID()
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
	xl := xlog.New().AppendPrefix("reqid: " + reqid)
	ctx := xlog.NewContext(context.Background(), xl)
	ctx = NewReqidContext(ctx, reqid)

	for _, p := range m.pingPlugins {
		res, retContent, err = p.Handle(ctx, OpPing, *content)
		if err != nil {
			xl.Warn("send NewWorkConn request to plugin [%s] error: %v", p.Name(), err)
			return nil, errors.New("send NewWorkConn request to plugin error")
		}
		if res.Reject {
			return nil, fmt.Errorf("%s", res.RejectReason)
		}
		if !res.Unchange {
			content = retContent.(*NewWorkConnContent)
		}
	}
	return content, nil
}
197 198 199 200 201 202 203 204 205 206 207 208 209 210

func (m *Manager) NewUserConn(content *NewUserConnContent) (*NewUserConnContent, error) {
	if len(m.newUserConnPlugins) == 0 {
		return content, nil
	}

	var (
		res = &Response{
			Reject:   false,
			Unchange: true,
		}
		retContent interface{}
		err        error
	)
F
fatedier 已提交
211
	reqid, _ := util.RandID()
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
	xl := xlog.New().AppendPrefix("reqid: " + reqid)
	ctx := xlog.NewContext(context.Background(), xl)
	ctx = NewReqidContext(ctx, reqid)

	for _, p := range m.newUserConnPlugins {
		res, retContent, err = p.Handle(ctx, OpNewUserConn, *content)
		if err != nil {
			xl.Info("send NewUserConn request to plugin [%s] error: %v", p.Name(), err)
			return nil, errors.New("send NewUserConn request to plugin error")
		}
		if res.Reject {
			return nil, fmt.Errorf("%s", res.RejectReason)
		}
		if !res.Unchange {
			content = retContent.(*NewUserConnContent)
		}
	}
	return content, nil
}