GoDoxy/internal/route/udp.go

149 lines
3.6 KiB
Go
Executable file

package route
// import (
// "errors"
// "fmt"
// "io"
// "net"
// "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"
// )
// type (
// UDPRoute struct {
// *StreamRoute
// connMap UDPConnMap
// listeningConn net.PacketConn
// targetAddr *net.UDPAddr
// }
// UDPConn struct {
// key string
// src net.Conn
// dst net.Conn
// U.BidirectionalPipe
// }
// UDPConnMap = F.Map[string, *UDPConn]
// )
// var NewUDPConnMap = F.NewMap[UDPConnMap]
// const udpBufferSize = 8192
// func NewUDPRoute(base *StreamRoute) *UDPRoute {
// return &UDPRoute{
// StreamRoute: base,
// connMap: NewUDPConnMap(),
// }
// }
// func (route *UDPRoute) Setup() error {
// var cfg net.ListenConfig
// source, err := cfg.ListenPacket(route.task.Context(), string(route.Scheme.ListeningScheme), fmt.Sprintf(":%v", route.Port.ListeningPort))
// if err != nil {
// return err
// }
// raddr, err := net.ResolveUDPAddr(string(route.Scheme.ProxyScheme), fmt.Sprintf("%s:%v", route.Host, route.Port.ProxyPort))
// if err != nil {
// source.Close()
// return err
// }
// //! this read the allocated listeningPort from original ':0'
// route.Port.ListeningPort = T.Port(source.LocalAddr().(*net.UDPAddr).Port)
// route.listeningConn = source
// route.targetAddr = raddr
// return nil
// }
// func (route *UDPRoute) Accept() (types.StreamConn, error) {
// in := route.listeningConn
// buffer := make([]byte, udpBufferSize)
// nRead, srcAddr, err := in.ReadFrom(buffer)
// if err != nil {
// return nil, err
// }
// if nRead == 0 {
// return nil, io.ErrShortBuffer
// }
// key := srcAddr.String()
// conn, ok := route.connMap.Load(key)
// if !ok {
// srcConn, err := net.Dial(srcAddr.Network(), srcAddr.String())
// if err != nil {
// return nil, err
// }
// dstConn, err := net.Dial(route.targetAddr.Network(), route.targetAddr.String())
// if err != nil {
// srcConn.Close()
// return nil, err
// }
// conn = &UDPConn{
// key,
// srcConn,
// dstConn,
// U.NewBidirectionalPipe(route.task.Context(), sourceRWCloser{in, dstConn}, sourceRWCloser{in, srcConn}),
// }
// route.connMap.Store(key, conn)
// }
// _, err = conn.dst.Write(buffer[:nRead])
// return conn, err
// }
// func (route *UDPRoute) Handle(c types.StreamConn) error {
// switch c := c.(type) {
// case *UDPConn:
// err := c.Start()
// route.connMap.Delete(c.key)
// c.Close()
// return err
// case *net.TCPConn:
// in := route.listeningConn
// srcConn, err := net.DialTCP("tcp", nil, c.RemoteAddr().(*net.TCPAddr))
// if err != nil {
// return err
// }
// err = U.NewBidirectionalPipe(route.task.Context(), sourceRWCloser{in, c}, sourceRWCloser{in, srcConn}).Start()
// c.Close()
// return err
// }
// return fmt.Errorf("unknown conn type: %T", c)
// }
// func (route *UDPRoute) Close() error {
// route.connMap.RangeAllParallel(func(k string, v *UDPConn) {
// v.Close()
// })
// route.connMap.Clear()
// return route.listeningConn.Close()
// }
// // Close implements types.StreamConn
// func (conn *UDPConn) Close() error {
// return errors.Join(conn.src.Close(), conn.dst.Close())
// }
// // RemoteAddr implements types.StreamConn
// func (conn *UDPConn) RemoteAddr() net.Addr {
// return conn.src.RemoteAddr()
// }
// type sourceRWCloser struct {
// server net.PacketConn
// net.Conn
// }
// func (w sourceRWCloser) Write(p []byte) (int, error) {
// return w.server.WriteTo(p, w.RemoteAddr().(*net.UDPAddr))
// }