mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00

- Incorrect name being shown on dashboard "Proxies page" - Apps being shown when homepage.show is false - Load balanced routes are shown on homepage instead of the load balancer - Route with idlewatcher will now be removed on container destroy - Idlewatcher panic - Performance improvement - Idlewatcher infinitely loading - Reload stucked / not working properly - Streams stuck on shutdown / reload - etc... Added: - support idlewatcher for loadbalanced routes - partial implementation for stream type idlewatcher Issues: - graceful shutdown
71 lines
1.6 KiB
Go
Executable file
71 lines
1.6 KiB
Go
Executable file
package route
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/yusing/go-proxy/internal/net/types"
|
|
T "github.com/yusing/go-proxy/internal/proxy/fields"
|
|
U "github.com/yusing/go-proxy/internal/utils"
|
|
F "github.com/yusing/go-proxy/internal/utils/functional"
|
|
)
|
|
|
|
const tcpDialTimeout = 5 * time.Second
|
|
|
|
type (
|
|
TCPConnMap = F.Map[net.Conn, struct{}]
|
|
TCPRoute struct {
|
|
*StreamRoute
|
|
listener *net.TCPListener
|
|
}
|
|
)
|
|
|
|
func NewTCPRoute(base *StreamRoute) *TCPRoute {
|
|
return &TCPRoute{StreamRoute: base}
|
|
}
|
|
|
|
func (route *TCPRoute) Setup() error {
|
|
in, err := net.Listen("tcp", fmt.Sprintf(":%v", route.Port.ListeningPort))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//! this read the allocated port from original ':0'
|
|
route.Port.ListeningPort = T.Port(in.Addr().(*net.TCPAddr).Port)
|
|
route.listener = in.(*net.TCPListener)
|
|
return nil
|
|
}
|
|
|
|
func (route *TCPRoute) Accept() (types.StreamConn, error) {
|
|
route.listener.SetDeadline(time.Now().Add(time.Second))
|
|
return route.listener.Accept()
|
|
}
|
|
|
|
func (route *TCPRoute) Handle(c types.StreamConn) error {
|
|
clientConn := c.(net.Conn)
|
|
|
|
defer clientConn.Close()
|
|
route.task.OnComplete("close conn", func() { clientConn.Close() })
|
|
|
|
ctx, cancel := context.WithTimeout(route.task.Context(), tcpDialTimeout)
|
|
|
|
serverAddr := fmt.Sprintf("%s:%v", route.Host, route.Port.ProxyPort)
|
|
dialer := &net.Dialer{}
|
|
|
|
serverConn, err := dialer.DialContext(ctx, string(route.Scheme.ProxyScheme), serverAddr)
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pipe := U.NewBidirectionalPipe(route.task.Context(), clientConn, serverConn)
|
|
return pipe.Start()
|
|
}
|
|
|
|
func (route *TCPRoute) CloseListeners() {
|
|
if route.listener == nil {
|
|
return
|
|
}
|
|
route.listener.Close()
|
|
}
|