mirror of
https://github.com/fatedier/frp.git
synced 2025-07-27 07:35:07 +00:00
change log method
This commit is contained in:
@@ -91,71 +91,3 @@ func Debug(format string, v ...interface{}) {
|
||||
func Trace(format string, v ...interface{}) {
|
||||
Log.Trace(format, v...)
|
||||
}
|
||||
|
||||
// Logger is the log interface
|
||||
type Logger interface {
|
||||
AddLogPrefix(string)
|
||||
GetPrefixStr() string
|
||||
GetAllPrefix() []string
|
||||
ClearLogPrefix()
|
||||
Error(string, ...interface{})
|
||||
Warn(string, ...interface{})
|
||||
Info(string, ...interface{})
|
||||
Debug(string, ...interface{})
|
||||
Trace(string, ...interface{})
|
||||
}
|
||||
|
||||
type PrefixLogger struct {
|
||||
prefix string
|
||||
allPrefix []string
|
||||
}
|
||||
|
||||
func NewPrefixLogger(prefix string) *PrefixLogger {
|
||||
logger := &PrefixLogger{
|
||||
allPrefix: make([]string, 0),
|
||||
}
|
||||
logger.AddLogPrefix(prefix)
|
||||
return logger
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) AddLogPrefix(prefix string) {
|
||||
if len(prefix) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
pl.prefix += "[" + prefix + "] "
|
||||
pl.allPrefix = append(pl.allPrefix, prefix)
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) GetPrefixStr() string {
|
||||
return pl.prefix
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) GetAllPrefix() []string {
|
||||
return pl.allPrefix
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) ClearLogPrefix() {
|
||||
pl.prefix = ""
|
||||
pl.allPrefix = make([]string, 0)
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) Error(format string, v ...interface{}) {
|
||||
Log.Error(pl.prefix+format, v...)
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) Warn(format string, v ...interface{}) {
|
||||
Log.Warn(pl.prefix+format, v...)
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) Info(format string, v ...interface{}) {
|
||||
Log.Info(pl.prefix+format, v...)
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) Debug(format string, v ...interface{}) {
|
||||
Log.Debug(pl.prefix+format, v...)
|
||||
}
|
||||
|
||||
func (pl *PrefixLogger) Trace(format string, v ...interface{}) {
|
||||
Log.Trace(pl.prefix+format, v...)
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -23,41 +24,64 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
gnet "github.com/fatedier/golib/net"
|
||||
kcp "github.com/fatedier/kcp-go"
|
||||
)
|
||||
|
||||
// Conn is the interface of connections used in frp.
|
||||
type Conn interface {
|
||||
net.Conn
|
||||
log.Logger
|
||||
type ContextGetter interface {
|
||||
Context() context.Context
|
||||
}
|
||||
|
||||
type WrapLogConn struct {
|
||||
net.Conn
|
||||
log.Logger
|
||||
type ContextSetter interface {
|
||||
WithContext(ctx context.Context)
|
||||
}
|
||||
|
||||
func WrapConn(c net.Conn) Conn {
|
||||
return &WrapLogConn{
|
||||
Conn: c,
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
func NewLogFromConn(conn net.Conn) *xlog.Logger {
|
||||
if c, ok := conn.(ContextGetter); ok {
|
||||
return xlog.FromContextSafe(c.Context())
|
||||
}
|
||||
return xlog.New()
|
||||
}
|
||||
|
||||
func NewContextFromConn(conn net.Conn) context.Context {
|
||||
if c, ok := conn.(ContextGetter); ok {
|
||||
return c.Context()
|
||||
}
|
||||
return context.Background()
|
||||
}
|
||||
|
||||
// ContextConn is the connection with context
|
||||
type ContextConn struct {
|
||||
net.Conn
|
||||
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewContextConn(c net.Conn, ctx context.Context) *ContextConn {
|
||||
return &ContextConn{
|
||||
Conn: c,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ContextConn) WithContext(ctx context.Context) {
|
||||
c.ctx = ctx
|
||||
}
|
||||
|
||||
func (c *ContextConn) Context() context.Context {
|
||||
return c.ctx
|
||||
}
|
||||
|
||||
type WrapReadWriteCloserConn struct {
|
||||
io.ReadWriteCloser
|
||||
log.Logger
|
||||
|
||||
underConn net.Conn
|
||||
}
|
||||
|
||||
func WrapReadWriteCloserToConn(rwc io.ReadWriteCloser, underConn net.Conn) Conn {
|
||||
func WrapReadWriteCloserToConn(rwc io.ReadWriteCloser, underConn net.Conn) net.Conn {
|
||||
return &WrapReadWriteCloserConn{
|
||||
ReadWriteCloser: rwc,
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
underConn: underConn,
|
||||
}
|
||||
}
|
||||
@@ -99,7 +123,6 @@ func (conn *WrapReadWriteCloserConn) SetWriteDeadline(t time.Time) error {
|
||||
|
||||
type CloseNotifyConn struct {
|
||||
net.Conn
|
||||
log.Logger
|
||||
|
||||
// 1 means closed
|
||||
closeFlag int32
|
||||
@@ -108,10 +131,9 @@ type CloseNotifyConn struct {
|
||||
}
|
||||
|
||||
// closeFn will be only called once
|
||||
func WrapCloseNotifyConn(c net.Conn, closeFn func()) Conn {
|
||||
func WrapCloseNotifyConn(c net.Conn, closeFn func()) net.Conn {
|
||||
return &CloseNotifyConn{
|
||||
Conn: c,
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
closeFn: closeFn,
|
||||
}
|
||||
}
|
||||
@@ -128,7 +150,7 @@ func (cc *CloseNotifyConn) Close() (err error) {
|
||||
}
|
||||
|
||||
type StatsConn struct {
|
||||
Conn
|
||||
net.Conn
|
||||
|
||||
closed int64 // 1 means closed
|
||||
totalRead int64
|
||||
@@ -136,7 +158,7 @@ type StatsConn struct {
|
||||
statsFunc func(totalRead, totalWrite int64)
|
||||
}
|
||||
|
||||
func WrapStatsConn(conn Conn, statsFunc func(total, totalWrite int64)) *StatsConn {
|
||||
func WrapStatsConn(conn net.Conn, statsFunc func(total, totalWrite int64)) *StatsConn {
|
||||
return &StatsConn{
|
||||
Conn: conn,
|
||||
statsFunc: statsFunc,
|
||||
@@ -166,10 +188,10 @@ func (statsConn *StatsConn) Close() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func ConnectServer(protocol string, addr string) (c Conn, err error) {
|
||||
func ConnectServer(protocol string, addr string) (c net.Conn, err error) {
|
||||
switch protocol {
|
||||
case "tcp":
|
||||
return ConnectTcpServer(addr)
|
||||
return net.Dial("tcp", addr)
|
||||
case "kcp":
|
||||
kcpConn, errRet := kcp.DialWithOptions(addr, nil, 10, 3)
|
||||
if errRet != nil {
|
||||
@@ -184,21 +206,17 @@ func ConnectServer(protocol string, addr string) (c Conn, err error) {
|
||||
kcpConn.SetACKNoDelay(false)
|
||||
kcpConn.SetReadBuffer(4194304)
|
||||
kcpConn.SetWriteBuffer(4194304)
|
||||
c = WrapConn(kcpConn)
|
||||
c = kcpConn
|
||||
return
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupport protocol: %s", protocol)
|
||||
}
|
||||
}
|
||||
|
||||
func ConnectServerByProxy(proxyUrl string, protocol string, addr string) (c Conn, err error) {
|
||||
func ConnectServerByProxy(proxyURL string, protocol string, addr string) (c net.Conn, err error) {
|
||||
switch protocol {
|
||||
case "tcp":
|
||||
var conn net.Conn
|
||||
if conn, err = gnet.DialTcpByProxy(proxyUrl, addr); err != nil {
|
||||
return
|
||||
}
|
||||
return WrapConn(conn), nil
|
||||
return gnet.DialTcpByProxy(proxyURL, addr)
|
||||
case "kcp":
|
||||
// http proxy is not supported for kcp
|
||||
return ConnectServer(protocol, addr)
|
||||
@@ -209,7 +227,7 @@ func ConnectServerByProxy(proxyUrl string, protocol string, addr string) (c Conn
|
||||
}
|
||||
}
|
||||
|
||||
func ConnectServerByProxyWithTLS(proxyUrl string, protocol string, addr string, tlsConfig *tls.Config) (c Conn, err error) {
|
||||
func ConnectServerByProxyWithTLS(proxyUrl string, protocol string, addr string, tlsConfig *tls.Config) (c net.Conn, err error) {
|
||||
c, err = ConnectServerByProxy(proxyUrl, protocol, addr)
|
||||
if err != nil {
|
||||
return
|
||||
|
@@ -18,17 +18,13 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
|
||||
kcp "github.com/fatedier/kcp-go"
|
||||
)
|
||||
|
||||
type KcpListener struct {
|
||||
net.Addr
|
||||
listener net.Listener
|
||||
accept chan Conn
|
||||
acceptCh chan net.Conn
|
||||
closeFlag bool
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func ListenKcp(bindAddr string, bindPort int) (l *KcpListener, err error) {
|
||||
@@ -40,11 +36,9 @@ func ListenKcp(bindAddr string, bindPort int) (l *KcpListener, err error) {
|
||||
listener.SetWriteBuffer(4194304)
|
||||
|
||||
l = &KcpListener{
|
||||
Addr: listener.Addr(),
|
||||
listener: listener,
|
||||
accept: make(chan Conn),
|
||||
acceptCh: make(chan net.Conn),
|
||||
closeFlag: false,
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -52,7 +46,7 @@ func ListenKcp(bindAddr string, bindPort int) (l *KcpListener, err error) {
|
||||
conn, err := listener.AcceptKCP()
|
||||
if err != nil {
|
||||
if l.closeFlag {
|
||||
close(l.accept)
|
||||
close(l.acceptCh)
|
||||
return
|
||||
}
|
||||
continue
|
||||
@@ -64,14 +58,14 @@ func ListenKcp(bindAddr string, bindPort int) (l *KcpListener, err error) {
|
||||
conn.SetWindowSize(1024, 1024)
|
||||
conn.SetACKNoDelay(false)
|
||||
|
||||
l.accept <- WrapConn(conn)
|
||||
l.acceptCh <- conn
|
||||
}
|
||||
}()
|
||||
return l, err
|
||||
}
|
||||
|
||||
func (l *KcpListener) Accept() (Conn, error) {
|
||||
conn, ok := <-l.accept
|
||||
func (l *KcpListener) Accept() (net.Conn, error) {
|
||||
conn, ok := <-l.acceptCh
|
||||
if !ok {
|
||||
return conn, fmt.Errorf("channel for kcp listener closed")
|
||||
}
|
||||
@@ -86,6 +80,10 @@ func (l *KcpListener) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *KcpListener) Addr() net.Addr {
|
||||
return l.listener.Addr()
|
||||
}
|
||||
|
||||
func NewKcpConnFromUdp(conn *net.UDPConn, connected bool, raddr string) (net.Conn, error) {
|
||||
kcpConn, err := kcp.NewConnEx(1, connected, raddr, nil, 10, 3, conn)
|
||||
if err != nil {
|
||||
|
@@ -19,65 +19,34 @@ import (
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
)
|
||||
|
||||
type Listener interface {
|
||||
Accept() (Conn, error)
|
||||
Close() error
|
||||
log.Logger
|
||||
}
|
||||
|
||||
type LogListener struct {
|
||||
l net.Listener
|
||||
net.Listener
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func WrapLogListener(l net.Listener) Listener {
|
||||
return &LogListener{
|
||||
l: l,
|
||||
Listener: l,
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
}
|
||||
}
|
||||
|
||||
func (logL *LogListener) Accept() (Conn, error) {
|
||||
c, err := logL.l.Accept()
|
||||
return WrapConn(c), err
|
||||
}
|
||||
|
||||
// Custom listener
|
||||
type CustomListener struct {
|
||||
conns chan Conn
|
||||
closed bool
|
||||
mu sync.Mutex
|
||||
|
||||
log.Logger
|
||||
acceptCh chan net.Conn
|
||||
closed bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewCustomListener() *CustomListener {
|
||||
return &CustomListener{
|
||||
conns: make(chan Conn, 64),
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
acceptCh: make(chan net.Conn, 64),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CustomListener) Accept() (Conn, error) {
|
||||
conn, ok := <-l.conns
|
||||
func (l *CustomListener) Accept() (net.Conn, error) {
|
||||
conn, ok := <-l.acceptCh
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("listener closed")
|
||||
}
|
||||
conn.AddLogPrefix(l.GetPrefixStr())
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (l *CustomListener) PutConn(conn Conn) error {
|
||||
func (l *CustomListener) PutConn(conn net.Conn) error {
|
||||
err := errors.PanicToError(func() {
|
||||
select {
|
||||
case l.conns <- conn:
|
||||
case l.acceptCh <- conn:
|
||||
default:
|
||||
conn.Close()
|
||||
}
|
||||
@@ -89,7 +58,7 @@ func (l *CustomListener) Close() error {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
if !l.closed {
|
||||
close(l.conns)
|
||||
close(l.acceptCh)
|
||||
l.closed = true
|
||||
}
|
||||
return nil
|
||||
|
111
utils/net/tcp.go
111
utils/net/tcp.go
@@ -1,111 +0,0 @@
|
||||
// Copyright 2016 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 net
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
)
|
||||
|
||||
type TcpListener struct {
|
||||
net.Addr
|
||||
listener net.Listener
|
||||
accept chan Conn
|
||||
closeFlag bool
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func ListenTcp(bindAddr string, bindPort int) (l *TcpListener, err error) {
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", bindAddr, bindPort))
|
||||
if err != nil {
|
||||
return l, err
|
||||
}
|
||||
listener, err := net.ListenTCP("tcp", tcpAddr)
|
||||
if err != nil {
|
||||
return l, err
|
||||
}
|
||||
|
||||
l = &TcpListener{
|
||||
Addr: listener.Addr(),
|
||||
listener: listener,
|
||||
accept: make(chan Conn),
|
||||
closeFlag: false,
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
conn, err := listener.AcceptTCP()
|
||||
if err != nil {
|
||||
if l.closeFlag {
|
||||
close(l.accept)
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
c := NewTcpConn(conn)
|
||||
l.accept <- c
|
||||
}
|
||||
}()
|
||||
return l, err
|
||||
}
|
||||
|
||||
// Wait util get one new connection or listener is closed
|
||||
// if listener is closed, err returned.
|
||||
func (l *TcpListener) Accept() (Conn, error) {
|
||||
conn, ok := <-l.accept
|
||||
if !ok {
|
||||
return conn, fmt.Errorf("channel for tcp listener closed")
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (l *TcpListener) Close() error {
|
||||
if !l.closeFlag {
|
||||
l.closeFlag = true
|
||||
l.listener.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Wrap for TCPConn.
|
||||
type TcpConn struct {
|
||||
net.Conn
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func NewTcpConn(conn net.Conn) (c *TcpConn) {
|
||||
c = &TcpConn{
|
||||
Conn: conn,
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ConnectTcpServer(addr string) (c Conn, err error) {
|
||||
servertAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
conn, err := net.DialTCP("tcp", nil, servertAddr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
c = NewTcpConn(conn)
|
||||
return
|
||||
}
|
@@ -26,13 +26,13 @@ var (
|
||||
FRP_TLS_HEAD_BYTE = 0x17
|
||||
)
|
||||
|
||||
func WrapTLSClientConn(c net.Conn, tlsConfig *tls.Config) (out Conn) {
|
||||
func WrapTLSClientConn(c net.Conn, tlsConfig *tls.Config) (out net.Conn) {
|
||||
c.Write([]byte{byte(FRP_TLS_HEAD_BYTE)})
|
||||
out = WrapConn(tls.Client(c, tlsConfig))
|
||||
out = tls.Client(c, tlsConfig)
|
||||
return
|
||||
}
|
||||
|
||||
func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, timeout time.Duration) (out Conn, err error) {
|
||||
func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, timeout time.Duration) (out net.Conn, err error) {
|
||||
sc, r := gnet.NewSharedConnSize(c, 2)
|
||||
buf := make([]byte, 1)
|
||||
var n int
|
||||
@@ -44,9 +44,9 @@ func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, t
|
||||
}
|
||||
|
||||
if n == 1 && int(buf[0]) == FRP_TLS_HEAD_BYTE {
|
||||
out = WrapConn(tls.Server(c, tlsConfig))
|
||||
out = tls.Server(c, tlsConfig)
|
||||
} else {
|
||||
out = WrapConn(sc)
|
||||
out = sc
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@@ -21,8 +21,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
|
||||
"github.com/fatedier/golib/pool"
|
||||
)
|
||||
|
||||
@@ -33,7 +31,6 @@ type UdpPacket struct {
|
||||
}
|
||||
|
||||
type FakeUdpConn struct {
|
||||
log.Logger
|
||||
l *UdpListener
|
||||
|
||||
localAddr net.Addr
|
||||
@@ -47,7 +44,6 @@ type FakeUdpConn struct {
|
||||
|
||||
func NewFakeUdpConn(l *UdpListener, laddr, raddr net.Addr) *FakeUdpConn {
|
||||
fc := &FakeUdpConn{
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
l: l,
|
||||
localAddr: laddr,
|
||||
remoteAddr: raddr,
|
||||
@@ -157,15 +153,13 @@ func (c *FakeUdpConn) SetWriteDeadline(t time.Time) error {
|
||||
}
|
||||
|
||||
type UdpListener struct {
|
||||
net.Addr
|
||||
accept chan Conn
|
||||
addr net.Addr
|
||||
acceptCh chan net.Conn
|
||||
writeCh chan *UdpPacket
|
||||
readConn net.Conn
|
||||
closeFlag bool
|
||||
|
||||
fakeConns map[string]*FakeUdpConn
|
||||
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func ListenUDP(bindAddr string, bindPort int) (l *UdpListener, err error) {
|
||||
@@ -176,11 +170,10 @@ func ListenUDP(bindAddr string, bindPort int) (l *UdpListener, err error) {
|
||||
readConn, err := net.ListenUDP("udp", udpAddr)
|
||||
|
||||
l = &UdpListener{
|
||||
Addr: udpAddr,
|
||||
accept: make(chan Conn),
|
||||
addr: udpAddr,
|
||||
acceptCh: make(chan net.Conn),
|
||||
writeCh: make(chan *UdpPacket, 1000),
|
||||
fakeConns: make(map[string]*FakeUdpConn),
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
}
|
||||
|
||||
// for reading
|
||||
@@ -189,19 +182,19 @@ func ListenUDP(bindAddr string, bindPort int) (l *UdpListener, err error) {
|
||||
buf := pool.GetBuf(1450)
|
||||
n, remoteAddr, err := readConn.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
close(l.accept)
|
||||
close(l.acceptCh)
|
||||
close(l.writeCh)
|
||||
return
|
||||
}
|
||||
|
||||
fakeConn, exist := l.fakeConns[remoteAddr.String()]
|
||||
if !exist || fakeConn.IsClosed() {
|
||||
fakeConn = NewFakeUdpConn(l, l.Addr, remoteAddr)
|
||||
fakeConn = NewFakeUdpConn(l, l.Addr(), remoteAddr)
|
||||
l.fakeConns[remoteAddr.String()] = fakeConn
|
||||
}
|
||||
fakeConn.putPacket(buf[:n])
|
||||
|
||||
l.accept <- fakeConn
|
||||
l.acceptCh <- fakeConn
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -226,7 +219,6 @@ func (l *UdpListener) writeUdpPacket(packet *UdpPacket) (err error) {
|
||||
defer func() {
|
||||
if errRet := recover(); errRet != nil {
|
||||
err = fmt.Errorf("udp write closed listener")
|
||||
l.Info("udp write closed listener")
|
||||
}
|
||||
}()
|
||||
l.writeCh <- packet
|
||||
@@ -243,8 +235,8 @@ func (l *UdpListener) WriteMsg(buf []byte, remoteAddr *net.UDPAddr) (err error)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *UdpListener) Accept() (Conn, error) {
|
||||
conn, ok := <-l.accept
|
||||
func (l *UdpListener) Accept() (net.Conn, error) {
|
||||
conn, ok := <-l.acceptCh
|
||||
if !ok {
|
||||
return conn, fmt.Errorf("channel for udp listener closed")
|
||||
}
|
||||
@@ -258,3 +250,7 @@ func (l *UdpListener) Close() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *UdpListener) Addr() net.Addr {
|
||||
return l.addr
|
||||
}
|
||||
|
@@ -8,8 +8,6 @@ import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
@@ -22,10 +20,8 @@ const (
|
||||
)
|
||||
|
||||
type WebsocketListener struct {
|
||||
net.Addr
|
||||
ln net.Listener
|
||||
accept chan Conn
|
||||
log.Logger
|
||||
ln net.Listener
|
||||
acceptCh chan net.Conn
|
||||
|
||||
server *http.Server
|
||||
httpMutex *http.ServeMux
|
||||
@@ -35,9 +31,7 @@ type WebsocketListener struct {
|
||||
// ln: tcp listener for websocket connections
|
||||
func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) {
|
||||
wl = &WebsocketListener{
|
||||
Addr: ln.Addr(),
|
||||
accept: make(chan Conn),
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
acceptCh: make(chan net.Conn),
|
||||
}
|
||||
|
||||
muxer := http.NewServeMux()
|
||||
@@ -46,7 +40,7 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) {
|
||||
conn := WrapCloseNotifyConn(c, func() {
|
||||
close(notifyCh)
|
||||
})
|
||||
wl.accept <- conn
|
||||
wl.acceptCh <- conn
|
||||
<-notifyCh
|
||||
}))
|
||||
|
||||
@@ -68,8 +62,8 @@ func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error)
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (p *WebsocketListener) Accept() (Conn, error) {
|
||||
c, ok := <-p.accept
|
||||
func (p *WebsocketListener) Accept() (net.Conn, error) {
|
||||
c, ok := <-p.acceptCh
|
||||
if !ok {
|
||||
return nil, ErrWebsocketListenerClosed
|
||||
}
|
||||
@@ -80,8 +74,12 @@ func (p *WebsocketListener) Close() error {
|
||||
return p.server.Close()
|
||||
}
|
||||
|
||||
func (p *WebsocketListener) Addr() net.Addr {
|
||||
return p.ln.Addr()
|
||||
}
|
||||
|
||||
// addr: domain:port
|
||||
func ConnectWebsocketServer(addr string) (Conn, error) {
|
||||
func ConnectWebsocketServer(addr string) (net.Conn, error) {
|
||||
addr = "ws://" + addr + FrpWebsocketPath
|
||||
uri, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
@@ -101,6 +99,5 @@ func ConnectWebsocketServer(addr string) (Conn, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := WrapConn(conn)
|
||||
return c, nil
|
||||
return conn, nil
|
||||
}
|
||||
|
@@ -17,11 +17,10 @@ package vhost
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
|
||||
gnet "github.com/fatedier/golib/net"
|
||||
"github.com/fatedier/golib/pool"
|
||||
)
|
||||
@@ -48,7 +47,7 @@ type HttpsMuxer struct {
|
||||
*VhostMuxer
|
||||
}
|
||||
|
||||
func NewHttpsMuxer(listener frpNet.Listener, timeout time.Duration) (*HttpsMuxer, error) {
|
||||
func NewHttpsMuxer(listener net.Listener, timeout time.Duration) (*HttpsMuxer, error) {
|
||||
mux, err := NewVhostMuxer(listener, GetHttpsHostname, nil, nil, timeout)
|
||||
return &HttpsMuxer{mux}, err
|
||||
}
|
||||
@@ -182,7 +181,7 @@ func readHandshake(rd io.Reader) (host string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func GetHttpsHostname(c frpNet.Conn) (_ frpNet.Conn, _ map[string]string, err error) {
|
||||
func GetHttpsHostname(c net.Conn) (_ net.Conn, _ map[string]string, err error) {
|
||||
reqInfoMap := make(map[string]string, 0)
|
||||
sc, rd := gnet.NewSharedConn(c)
|
||||
host, err := readHandshake(rd)
|
||||
@@ -191,5 +190,5 @@ func GetHttpsHostname(c frpNet.Conn) (_ frpNet.Conn, _ map[string]string, err er
|
||||
}
|
||||
reqInfoMap["Host"] = host
|
||||
reqInfoMap["Scheme"] = "https"
|
||||
return frpNet.WrapConn(sc), reqInfoMap, nil
|
||||
return sc, reqInfoMap, nil
|
||||
}
|
||||
|
@@ -13,22 +13,25 @@
|
||||
package vhost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
)
|
||||
|
||||
type muxFunc func(frpNet.Conn) (frpNet.Conn, map[string]string, error)
|
||||
type httpAuthFunc func(frpNet.Conn, string, string, string) (bool, error)
|
||||
type hostRewriteFunc func(frpNet.Conn, string) (frpNet.Conn, error)
|
||||
type muxFunc func(net.Conn) (net.Conn, map[string]string, error)
|
||||
type httpAuthFunc func(net.Conn, string, string, string) (bool, error)
|
||||
type hostRewriteFunc func(net.Conn, string) (net.Conn, error)
|
||||
|
||||
type VhostMuxer struct {
|
||||
listener frpNet.Listener
|
||||
listener net.Listener
|
||||
timeout time.Duration
|
||||
vhostFunc muxFunc
|
||||
authFunc httpAuthFunc
|
||||
@@ -36,7 +39,7 @@ type VhostMuxer struct {
|
||||
registryRouter *VhostRouters
|
||||
}
|
||||
|
||||
func NewVhostMuxer(listener frpNet.Listener, vhostFunc muxFunc, authFunc httpAuthFunc, rewriteFunc hostRewriteFunc, timeout time.Duration) (mux *VhostMuxer, err error) {
|
||||
func NewVhostMuxer(listener net.Listener, vhostFunc muxFunc, authFunc httpAuthFunc, rewriteFunc hostRewriteFunc, timeout time.Duration) (mux *VhostMuxer, err error) {
|
||||
mux = &VhostMuxer{
|
||||
listener: listener,
|
||||
timeout: timeout,
|
||||
@@ -49,7 +52,7 @@ func NewVhostMuxer(listener frpNet.Listener, vhostFunc muxFunc, authFunc httpAut
|
||||
return mux, nil
|
||||
}
|
||||
|
||||
type CreateConnFunc func(remoteAddr string) (frpNet.Conn, error)
|
||||
type CreateConnFunc func(remoteAddr string) (net.Conn, error)
|
||||
|
||||
// VhostRouteConfig is the params used to match HTTP requests
|
||||
type VhostRouteConfig struct {
|
||||
@@ -65,7 +68,7 @@ type VhostRouteConfig struct {
|
||||
|
||||
// listen for a new domain name, if rewriteHost is not empty and rewriteFunc is not nil
|
||||
// then rewrite the host header to rewriteHost
|
||||
func (v *VhostMuxer) Listen(cfg *VhostRouteConfig) (l *Listener, err error) {
|
||||
func (v *VhostMuxer) Listen(ctx context.Context, cfg *VhostRouteConfig) (l *Listener, err error) {
|
||||
l = &Listener{
|
||||
name: cfg.Domain,
|
||||
location: cfg.Location,
|
||||
@@ -73,8 +76,8 @@ func (v *VhostMuxer) Listen(cfg *VhostRouteConfig) (l *Listener, err error) {
|
||||
userName: cfg.Username,
|
||||
passWord: cfg.Password,
|
||||
mux: v,
|
||||
accept: make(chan frpNet.Conn),
|
||||
Logger: log.NewPrefixLogger(""),
|
||||
accept: make(chan net.Conn),
|
||||
ctx: ctx,
|
||||
}
|
||||
err = v.registryRouter.Add(cfg.Domain, cfg.Location, l)
|
||||
if err != nil {
|
||||
@@ -123,7 +126,7 @@ func (v *VhostMuxer) run() {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *VhostMuxer) handle(c frpNet.Conn) {
|
||||
func (v *VhostMuxer) handle(c net.Conn) {
|
||||
if err := c.SetDeadline(time.Now().Add(v.timeout)); err != nil {
|
||||
c.Close()
|
||||
return
|
||||
@@ -146,13 +149,14 @@ func (v *VhostMuxer) handle(c frpNet.Conn) {
|
||||
c.Close()
|
||||
return
|
||||
}
|
||||
xl := xlog.FromContextSafe(l.ctx)
|
||||
|
||||
// if authFunc is exist and userName/password is set
|
||||
// then verify user access
|
||||
if l.mux.authFunc != nil && l.userName != "" && l.passWord != "" {
|
||||
bAccess, err := l.mux.authFunc(c, l.userName, l.passWord, reqInfoMap["Authorization"])
|
||||
if bAccess == false || err != nil {
|
||||
l.Debug("check http Authorization failed")
|
||||
xl.Debug("check http Authorization failed")
|
||||
res := noAuthResponse()
|
||||
res.Write(c)
|
||||
c.Close()
|
||||
@@ -166,12 +170,12 @@ func (v *VhostMuxer) handle(c frpNet.Conn) {
|
||||
}
|
||||
c = sConn
|
||||
|
||||
l.Debug("get new http request host [%s] path [%s]", name, path)
|
||||
xl.Debug("get new http request host [%s] path [%s]", name, path)
|
||||
err = errors.PanicToError(func() {
|
||||
l.accept <- c
|
||||
})
|
||||
if err != nil {
|
||||
l.Warn("listener is already closed, ignore this request")
|
||||
xl.Warn("listener is already closed, ignore this request")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,11 +186,12 @@ type Listener struct {
|
||||
userName string
|
||||
passWord string
|
||||
mux *VhostMuxer // for closing VhostMuxer
|
||||
accept chan frpNet.Conn
|
||||
log.Logger
|
||||
accept chan net.Conn
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (l *Listener) Accept() (frpNet.Conn, error) {
|
||||
func (l *Listener) Accept() (net.Conn, error) {
|
||||
xl := xlog.FromContextSafe(l.ctx)
|
||||
conn, ok := <-l.accept
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Listener closed")
|
||||
@@ -198,17 +203,13 @@ func (l *Listener) Accept() (frpNet.Conn, error) {
|
||||
if l.mux.rewriteFunc != nil {
|
||||
sConn, err := l.mux.rewriteFunc(conn, l.rewriteHost)
|
||||
if err != nil {
|
||||
l.Warn("host header rewrite failed: %v", err)
|
||||
xl.Warn("host header rewrite failed: %v", err)
|
||||
return nil, fmt.Errorf("host header rewrite failed")
|
||||
}
|
||||
l.Debug("rewrite host to [%s] success", l.rewriteHost)
|
||||
xl.Debug("rewrite host to [%s] success", l.rewriteHost)
|
||||
conn = sConn
|
||||
}
|
||||
|
||||
for _, prefix := range l.GetAllPrefix() {
|
||||
conn.AddLogPrefix(prefix)
|
||||
}
|
||||
return conn, nil
|
||||
return frpNet.NewContextConn(conn, l.ctx), nil
|
||||
}
|
||||
|
||||
func (l *Listener) Close() error {
|
||||
@@ -220,3 +221,7 @@ func (l *Listener) Close() error {
|
||||
func (l *Listener) Name() string {
|
||||
return l.name
|
||||
}
|
||||
|
||||
func (l *Listener) Addr() net.Addr {
|
||||
return (*net.TCPAddr)(nil)
|
||||
}
|
||||
|
42
utils/xlog/ctx.go
Normal file
42
utils/xlog/ctx.go
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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 xlog
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type key int
|
||||
|
||||
const (
|
||||
xlogKey key = 0
|
||||
)
|
||||
|
||||
func NewContext(ctx context.Context, xl *Logger) context.Context {
|
||||
return context.WithValue(ctx, xlogKey, xl)
|
||||
}
|
||||
|
||||
func FromContext(ctx context.Context) (xl *Logger, ok bool) {
|
||||
xl, ok = ctx.Value(xlogKey).(*Logger)
|
||||
return
|
||||
}
|
||||
|
||||
func FromContextSafe(ctx context.Context) *Logger {
|
||||
xl, ok := ctx.Value(xlogKey).(*Logger)
|
||||
if !ok {
|
||||
xl = New()
|
||||
}
|
||||
return xl
|
||||
}
|
73
utils/xlog/xlog.go
Normal file
73
utils/xlog/xlog.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// 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 xlog
|
||||
|
||||
import (
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
)
|
||||
|
||||
// Logger is not thread safety for operations on prefix
|
||||
type Logger struct {
|
||||
prefixes []string
|
||||
|
||||
prefixString string
|
||||
}
|
||||
|
||||
func New() *Logger {
|
||||
return &Logger{
|
||||
prefixes: make([]string, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) ResetPrefixes() (old []string) {
|
||||
old = l.prefixes
|
||||
l.prefixes = make([]string, 0)
|
||||
l.prefixString = ""
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Logger) AppendPrefix(prefix string) *Logger {
|
||||
l.prefixes = append(l.prefixes, prefix)
|
||||
l.prefixString += "[" + prefix + "] "
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Logger) Spawn() *Logger {
|
||||
nl := New()
|
||||
for _, v := range l.prefixes {
|
||||
nl.AppendPrefix(v)
|
||||
}
|
||||
return nl
|
||||
}
|
||||
|
||||
func (l *Logger) Error(format string, v ...interface{}) {
|
||||
log.Log.Error(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Warn(format string, v ...interface{}) {
|
||||
log.Log.Warn(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Info(format string, v ...interface{}) {
|
||||
log.Log.Info(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(format string, v ...interface{}) {
|
||||
log.Log.Debug(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Trace(format string, v ...interface{}) {
|
||||
log.Log.Trace(l.prefixString+format, v...)
|
||||
}
|
Reference in New Issue
Block a user