diff --git a/adapter/outbound/base.go b/adapter/outbound/base.go index b69311f6..a9615be0 100644 --- a/adapter/outbound/base.go +++ b/adapter/outbound/base.go @@ -210,6 +210,8 @@ func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn { type packetConn struct { net.PacketConn chain C.Chain + adapterName string + connID string actualRemoteDestination string } @@ -227,8 +229,14 @@ func (c *packetConn) AppendToChains(a C.ProxyAdapter) { c.chain = append(c.chain, a.Name()) } +func (c *packetConn) LocalAddr() net.Addr { + lAddr := c.PacketConn.LocalAddr() + return N.NewCustomAddr(c.adapterName, c.connID, lAddr) // make quic-go's connMultiplexer happy +} + func newPacketConn(pc net.PacketConn, a C.ProxyAdapter) C.PacketConn { - return &packetConn{pc, []string{a.Name()}, parseRemoteDestination(a.Addr())} + id, _ := utils.UnsafeUUIDGenerator.NewV4() + return &packetConn{pc, []string{a.Name()}, a.Name(), id.String(), parseRemoteDestination(a.Addr())} } func parseRemoteDestination(addr string) string { diff --git a/common/net/addr.go b/common/net/addr.go new file mode 100644 index 00000000..4efaefcd --- /dev/null +++ b/common/net/addr.go @@ -0,0 +1,36 @@ +package net + +import ( + "net" +) + +type CustomAddr interface { + net.Addr + RawAddr() net.Addr +} + +type customAddr struct { + networkStr string + addrStr string + rawAddr net.Addr +} + +func (a customAddr) Network() string { + return a.networkStr +} + +func (a customAddr) String() string { + return a.addrStr +} + +func (a customAddr) RawAddr() net.Addr { + return a.rawAddr +} + +func NewCustomAddr(networkStr string, addrStr string, rawAddr net.Addr) CustomAddr { + return customAddr{ + networkStr: networkStr, + addrStr: addrStr, + rawAddr: rawAddr, + } +} diff --git a/transport/tuic/conn.go b/transport/tuic/conn.go index ee687425..dfa43e1f 100644 --- a/transport/tuic/conn.go +++ b/transport/tuic/conn.go @@ -250,29 +250,7 @@ func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err erro } func (q *quicStreamPacketConn) LocalAddr() net.Addr { - addr := q.quicConn.LocalAddr() - if q.inputConn != nil { // client - return &packetAddr{addrStr: q.quicConn.LocalAddr().String(), connId: q.connId, rawAddr: addr} - } - return addr // server + return q.quicConn.LocalAddr() } var _ net.PacketConn = &quicStreamPacketConn{} - -type packetAddr struct { - addrStr string - connId uint32 - rawAddr net.Addr -} - -func (a packetAddr) Network() string { - return "tuic" -} - -func (a packetAddr) String() string { - return fmt.Sprintf("%s-%d", a.addrStr, a.connId) -} - -func (a packetAddr) RawAddr() net.Addr { - return a.rawAddr -} diff --git a/transport/tuic/server.go b/transport/tuic/server.go index 770e1869..b23f3ae9 100644 --- a/transport/tuic/server.go +++ b/transport/tuic/server.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "crypto/tls" + "fmt" "net" "sync" "sync/atomic" @@ -153,7 +154,7 @@ func (s *serverHandler) parsePacket(packet Packet, udpRelayMode string) (err err return s.HandleUdpFn(packet.ADDR.SocksAddr(), &serverUDPPacket{ pc: pc, packet: &packet, - rAddr: &packetAddr{addrStr: "tuic-" + s.uuid.String(), connId: assocId, rawAddr: s.quicConn.RemoteAddr()}, + rAddr: N.NewCustomAddr("tuic", fmt.Sprintf("tuic-%s-%d", s.uuid, assocId), s.quicConn.RemoteAddr()), // for tunnel's handleUDPConn }) }