change log method

This commit is contained in:
fatedier
2019-10-12 20:13:12 +08:00
parent 5dc8175fc8
commit 649f47c345
44 changed files with 670 additions and 688 deletions

View File

@ -36,6 +36,7 @@ type HttpProxy struct {
}
func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
xl := pxy.xl
routeConfig := vhost.VhostRouteConfig{
RewriteHost: pxy.cfg.HostHeaderRewrite,
Headers: pxy.cfg.Headers,
@ -88,7 +89,7 @@ func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
})
}
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHttpPort)))
pxy.Info("http proxy listen for host [%s] location [%s] group [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group)
xl.Info("http proxy listen for host [%s] location [%s] group [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group)
}
}
@ -120,7 +121,7 @@ func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
}
addrs = append(addrs, util.CanonicalAddr(tmpDomain, pxy.serverCfg.VhostHttpPort))
pxy.Info("http proxy listen for host [%s] location [%s] group [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group)
xl.Info("http proxy listen for host [%s] location [%s] group [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group)
}
}
remoteAddr = strings.Join(addrs, ",")
@ -131,10 +132,11 @@ func (pxy *HttpProxy) GetConf() config.ProxyConf {
return pxy.cfg
}
func (pxy *HttpProxy) GetRealConn(remoteAddr string) (workConn frpNet.Conn, err error) {
func (pxy *HttpProxy) GetRealConn(remoteAddr string) (workConn net.Conn, err error) {
xl := pxy.xl
rAddr, errRet := net.ResolveTCPAddr("tcp", remoteAddr)
if errRet != nil {
pxy.Warn("resolve TCP addr [%s] error: %v", remoteAddr, errRet)
xl.Warn("resolve TCP addr [%s] error: %v", remoteAddr, errRet)
// we do not return error here since remoteAddr is not necessary for proxies without proxy protocol enabled
}
@ -148,7 +150,7 @@ func (pxy *HttpProxy) GetRealConn(remoteAddr string) (workConn frpNet.Conn, err
if pxy.cfg.UseEncryption {
rwc, err = frpIo.WithEncryption(rwc, []byte(pxy.serverCfg.Token))
if err != nil {
pxy.Error("create encryption stream error: %v", err)
xl.Error("create encryption stream error: %v", err)
return
}
}

View File

@ -28,6 +28,7 @@ type HttpsProxy struct {
}
func (pxy *HttpsProxy) Run() (remoteAddr string, err error) {
xl := pxy.xl
routeConfig := &vhost.VhostRouteConfig{}
defer func() {
@ -42,26 +43,24 @@ func (pxy *HttpsProxy) Run() (remoteAddr string, err error) {
}
routeConfig.Domain = domain
l, errRet := pxy.rc.VhostHttpsMuxer.Listen(routeConfig)
l, errRet := pxy.rc.VhostHttpsMuxer.Listen(pxy.ctx, routeConfig)
if errRet != nil {
err = errRet
return
}
l.AddLogPrefix(pxy.name)
pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
xl.Info("https proxy listen for host [%s]", routeConfig.Domain)
pxy.listeners = append(pxy.listeners, l)
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHttpsPort))
}
if pxy.cfg.SubDomain != "" {
routeConfig.Domain = pxy.cfg.SubDomain + "." + pxy.serverCfg.SubDomainHost
l, errRet := pxy.rc.VhostHttpsMuxer.Listen(routeConfig)
l, errRet := pxy.rc.VhostHttpsMuxer.Listen(pxy.ctx, routeConfig)
if errRet != nil {
err = errRet
return
}
l.AddLogPrefix(pxy.name)
pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
xl.Info("https proxy listen for host [%s]", routeConfig.Domain)
pxy.listeners = append(pxy.listeners, l)
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHttpsPort)))
}

View File

@ -15,6 +15,7 @@
package proxy
import (
"context"
"fmt"
"io"
"net"
@ -25,48 +26,54 @@ import (
"github.com/fatedier/frp/models/msg"
"github.com/fatedier/frp/server/controller"
"github.com/fatedier/frp/server/stats"
"github.com/fatedier/frp/utils/log"
frpNet "github.com/fatedier/frp/utils/net"
"github.com/fatedier/frp/utils/xlog"
frpIo "github.com/fatedier/golib/io"
)
type GetWorkConnFn func() (frpNet.Conn, error)
type GetWorkConnFn func() (net.Conn, error)
type Proxy interface {
Context() context.Context
Run() (remoteAddr string, err error)
GetName() string
GetConf() config.ProxyConf
GetWorkConnFromPool(src, dst net.Addr) (workConn frpNet.Conn, err error)
GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn, err error)
GetUsedPortsNum() int
Close()
log.Logger
}
type BaseProxy struct {
name string
rc *controller.ResourceController
statsCollector stats.Collector
listeners []frpNet.Listener
listeners []net.Listener
usedPortsNum int
poolCount int
getWorkConnFn GetWorkConnFn
serverCfg config.ServerCommonConf
mu sync.RWMutex
log.Logger
mu sync.RWMutex
xl *xlog.Logger
ctx context.Context
}
func (pxy *BaseProxy) GetName() string {
return pxy.name
}
func (pxy *BaseProxy) Context() context.Context {
return pxy.ctx
}
func (pxy *BaseProxy) GetUsedPortsNum() int {
return pxy.usedPortsNum
}
func (pxy *BaseProxy) Close() {
pxy.Info("proxy closing")
xl := xlog.FromContextSafe(pxy.ctx)
xl.Info("proxy closing")
for _, l := range pxy.listeners {
l.Close()
}
@ -74,15 +81,17 @@ func (pxy *BaseProxy) Close() {
// GetWorkConnFromPool try to get a new work connections from pool
// for quickly response, we immediately send the StartWorkConn message to frpc after take out one from pool
func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn frpNet.Conn, err error) {
func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn, err error) {
xl := xlog.FromContextSafe(pxy.ctx)
// try all connections from the pool
for i := 0; i < pxy.poolCount+1; i++ {
if workConn, err = pxy.getWorkConnFn(); err != nil {
pxy.Warn("failed to get work connection: %v", err)
xl.Warn("failed to get work connection: %v", err)
return
}
pxy.Info("get a new work connection: [%s]", workConn.RemoteAddr().String())
workConn.AddLogPrefix(pxy.GetName())
xl.Info("get a new work connection: [%s]", workConn.RemoteAddr().String())
xl.Spawn().AppendPrefix(pxy.GetName())
workConn = frpNet.NewContextConn(workConn, pxy.ctx)
var (
srcAddr string
@ -109,7 +118,7 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn frpNet.Co
DstPort: uint16(dstPort),
})
if err != nil {
workConn.Warn("failed to send message to work connection from pool: %v, times: %d", err, i)
xl.Warn("failed to send message to work connection from pool: %v, times: %d", err, i)
workConn.Close()
} else {
break
@ -117,7 +126,7 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn frpNet.Co
}
if err != nil {
pxy.Error("try to get work connection failed in the end")
xl.Error("try to get work connection failed in the end")
return
}
return
@ -126,36 +135,39 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn frpNet.Co
// startListenHandler start a goroutine handler for each listener.
// p: p will just be passed to handler(Proxy, frpNet.Conn).
// handler: each proxy type can set different handler function to deal with connections accepted from listeners.
func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, frpNet.Conn, stats.Collector, config.ServerCommonConf)) {
func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, net.Conn, stats.Collector, config.ServerCommonConf)) {
xl := xlog.FromContextSafe(pxy.ctx)
for _, listener := range pxy.listeners {
go func(l frpNet.Listener) {
go func(l net.Listener) {
for {
// block
// if listener is closed, err returned
c, err := l.Accept()
if err != nil {
pxy.Info("listener is closed")
xl.Info("listener is closed")
return
}
pxy.Debug("get a user connection [%s]", c.RemoteAddr().String())
xl.Debug("get a user connection [%s]", c.RemoteAddr().String())
go handler(p, c, pxy.statsCollector, pxy.serverCfg)
}
}(listener)
}
}
func NewProxy(runId string, rc *controller.ResourceController, statsCollector stats.Collector, poolCount int,
func NewProxy(ctx context.Context, runId string, rc *controller.ResourceController, statsCollector stats.Collector, poolCount int,
getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf) (pxy Proxy, err error) {
xl := xlog.FromContextSafe(ctx).Spawn().AppendPrefix(pxyConf.GetBaseInfo().ProxyName)
basePxy := BaseProxy{
name: pxyConf.GetBaseInfo().ProxyName,
rc: rc,
statsCollector: statsCollector,
listeners: make([]frpNet.Listener, 0),
listeners: make([]net.Listener, 0),
poolCount: poolCount,
getWorkConnFn: getWorkConnFn,
Logger: log.NewPrefixLogger(runId),
serverCfg: serverCfg,
xl: xl,
ctx: xlog.NewContext(ctx, xl),
}
switch cfg := pxyConf.(type) {
case *config.TcpProxyConf:
@ -193,13 +205,13 @@ func NewProxy(runId string, rc *controller.ResourceController, statsCollector st
default:
return pxy, fmt.Errorf("proxy type not support")
}
pxy.AddLogPrefix(pxy.GetName())
return
}
// HandleUserTcpConnection is used for incoming tcp user connections.
// It can be used for tcp, http, https type.
func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn, statsCollector stats.Collector, serverCfg config.ServerCommonConf) {
func HandleUserTcpConnection(pxy Proxy, userConn net.Conn, statsCollector stats.Collector, serverCfg config.ServerCommonConf) {
xl := xlog.FromContextSafe(pxy.Context())
defer userConn.Close()
// try all connections from the pool
@ -211,17 +223,18 @@ func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn, statsCollector sta
var local io.ReadWriteCloser = workConn
cfg := pxy.GetConf().GetBaseInfo()
xl.Trace("handler user tcp connection, use_encryption: %t, use_compression: %t", cfg.UseEncryption, cfg.UseCompression)
if cfg.UseEncryption {
local, err = frpIo.WithEncryption(local, []byte(serverCfg.Token))
if err != nil {
pxy.Error("create encryption stream error: %v", err)
xl.Error("create encryption stream error: %v", err)
return
}
}
if cfg.UseCompression {
local = frpIo.WithCompression(local)
}
pxy.Debug("join connections, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", workConn.LocalAddr().String(),
xl.Debug("join connections, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", workConn.LocalAddr().String(),
workConn.RemoteAddr().String(), userConn.LocalAddr().String(), userConn.RemoteAddr().String())
statsCollector.Mark(stats.TypeOpenConnection, &stats.OpenConnectionPayload{ProxyName: pxy.GetName()})
@ -235,7 +248,7 @@ func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn, statsCollector sta
ProxyName: pxy.GetName(),
TrafficBytes: outCount,
})
pxy.Debug("join connections closed")
xl.Debug("join connections closed")
}
type ProxyManager struct {

View File

@ -24,14 +24,14 @@ type StcpProxy struct {
}
func (pxy *StcpProxy) Run() (remoteAddr string, err error) {
xl := pxy.xl
listener, errRet := pxy.rc.VisitorManager.Listen(pxy.GetName(), pxy.cfg.Sk)
if errRet != nil {
err = errRet
return
}
listener.AddLogPrefix(pxy.name)
pxy.listeners = append(pxy.listeners, listener)
pxy.Info("stcp proxy custom listen success")
xl.Info("stcp proxy custom listen success")
pxy.startListenHandler(pxy, HandleUserTcpConnection)
return

View File

@ -16,9 +16,9 @@ package proxy
import (
"fmt"
"net"
"github.com/fatedier/frp/models/config"
frpNet "github.com/fatedier/frp/utils/net"
)
type TcpProxy struct {
@ -29,6 +29,7 @@ type TcpProxy struct {
}
func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
xl := pxy.xl
if pxy.cfg.Group != "" {
l, realPort, errRet := pxy.rc.TcpGroupCtl.Listen(pxy.name, pxy.cfg.Group, pxy.cfg.GroupKey, pxy.serverCfg.ProxyBindAddr, pxy.cfg.RemotePort)
if errRet != nil {
@ -41,10 +42,8 @@ func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
}
}()
pxy.realPort = realPort
listener := frpNet.WrapLogListener(l)
listener.AddLogPrefix(pxy.name)
pxy.listeners = append(pxy.listeners, listener)
pxy.Info("tcp proxy listen port [%d] in group [%s]", pxy.cfg.RemotePort, pxy.cfg.Group)
pxy.listeners = append(pxy.listeners, l)
xl.Info("tcp proxy listen port [%d] in group [%s]", pxy.cfg.RemotePort, pxy.cfg.Group)
} else {
pxy.realPort, err = pxy.rc.TcpPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
if err != nil {
@ -55,14 +54,13 @@ func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
pxy.rc.TcpPortManager.Release(pxy.realPort)
}
}()
listener, errRet := frpNet.ListenTcp(pxy.serverCfg.ProxyBindAddr, pxy.realPort)
listener, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", pxy.serverCfg.ProxyBindAddr, pxy.realPort))
if errRet != nil {
err = errRet
return
}
listener.AddLogPrefix(pxy.name)
pxy.listeners = append(pxy.listeners, listener)
pxy.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
xl.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
}
pxy.cfg.RemotePort = pxy.realPort

View File

@ -54,6 +54,7 @@ type UdpProxy struct {
}
func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
xl := pxy.xl
pxy.realPort, err = pxy.rc.UdpPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
if err != nil {
return
@ -74,10 +75,10 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
udpConn, errRet := net.ListenUDP("udp", addr)
if errRet != nil {
err = errRet
pxy.Warn("listen udp port error: %v", err)
xl.Warn("listen udp port error: %v", err)
return
}
pxy.Info("udp proxy listen port [%d]", pxy.cfg.RemotePort)
xl.Info("udp proxy listen port [%d]", pxy.cfg.RemotePort)
pxy.udpConn = udpConn
pxy.sendCh = make(chan *msg.UdpPacket, 1024)
@ -91,11 +92,11 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
rawMsg msg.Message
errRet error
)
pxy.Trace("loop waiting message from udp workConn")
xl.Trace("loop waiting message from udp workConn")
// client will send heartbeat in workConn for keeping alive
conn.SetReadDeadline(time.Now().Add(time.Duration(60) * time.Second))
if rawMsg, errRet = msg.ReadMsg(conn); errRet != nil {
pxy.Warn("read from workConn for udp error: %v", errRet)
xl.Warn("read from workConn for udp error: %v", errRet)
conn.Close()
// notify proxy to start a new work connection
// ignore error here, it means the proxy is closed
@ -107,11 +108,11 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
conn.SetReadDeadline(time.Time{})
switch m := rawMsg.(type) {
case *msg.Ping:
pxy.Trace("udp work conn get ping message")
xl.Trace("udp work conn get ping message")
continue
case *msg.UdpPacket:
if errRet := errors.PanicToError(func() {
pxy.Trace("get udp message from workConn: %s", m.Content)
xl.Trace("get udp message from workConn: %s", m.Content)
pxy.readCh <- m
pxy.statsCollector.Mark(stats.TypeAddTrafficOut, &stats.AddTrafficOutPayload{
ProxyName: pxy.GetName(),
@ -119,7 +120,7 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
})
}); errRet != nil {
conn.Close()
pxy.Info("reader goroutine for udp work connection closed")
xl.Info("reader goroutine for udp work connection closed")
return
}
}
@ -133,15 +134,15 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
select {
case udpMsg, ok := <-pxy.sendCh:
if !ok {
pxy.Info("sender goroutine for udp work connection closed")
xl.Info("sender goroutine for udp work connection closed")
return
}
if errRet = msg.WriteMsg(conn, udpMsg); errRet != nil {
pxy.Info("sender goroutine for udp work connection closed: %v", errRet)
xl.Info("sender goroutine for udp work connection closed: %v", errRet)
conn.Close()
return
} else {
pxy.Trace("send message to udp workConn: %s", udpMsg.Content)
xl.Trace("send message to udp workConn: %s", udpMsg.Content)
pxy.statsCollector.Mark(stats.TypeAddTrafficIn, &stats.AddTrafficInPayload{
ProxyName: pxy.GetName(),
TrafficBytes: int64(len(udpMsg.Content)),
@ -149,7 +150,7 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
continue
}
case <-ctx.Done():
pxy.Info("sender goroutine for udp work connection closed")
xl.Info("sender goroutine for udp work connection closed")
return
}
}

View File

@ -31,8 +31,10 @@ type XtcpProxy struct {
}
func (pxy *XtcpProxy) Run() (remoteAddr string, err error) {
xl := pxy.xl
if pxy.rc.NatHoleController == nil {
pxy.Error("udp port for xtcp is not specified.")
xl.Error("udp port for xtcp is not specified.")
err = fmt.Errorf("xtcp is not supported in frps")
return
}
@ -53,7 +55,7 @@ func (pxy *XtcpProxy) Run() (remoteAddr string, err error) {
}
errRet = msg.WriteMsg(workConn, m)
if errRet != nil {
pxy.Warn("write nat hole sid package error, %v", errRet)
xl.Warn("write nat hole sid package error, %v", errRet)
workConn.Close()
break
}
@ -61,12 +63,12 @@ func (pxy *XtcpProxy) Run() (remoteAddr string, err error) {
go func() {
raw, errRet := msg.ReadMsg(workConn)
if errRet != nil {
pxy.Warn("read nat hole client ok package error: %v", errRet)
xl.Warn("read nat hole client ok package error: %v", errRet)
workConn.Close()
return
}
if _, ok := raw.(*msg.NatHoleClientDetectOK); !ok {
pxy.Warn("read nat hole client ok package format error")
xl.Warn("read nat hole client ok package format error")
workConn.Close()
return
}