packet.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package singbridge
  2. import (
  3. "context"
  4. B "github.com/sagernet/sing/common/buf"
  5. "github.com/sagernet/sing/common/bufio"
  6. M "github.com/sagernet/sing/common/metadata"
  7. "github.com/xtls/xray-core/common/buf"
  8. "github.com/xtls/xray-core/common/net"
  9. "github.com/xtls/xray-core/transport"
  10. )
  11. func CopyPacketConn(ctx context.Context, inboundConn net.Conn, link *transport.Link, destination net.Destination, serverConn net.PacketConn) error {
  12. conn := &PacketConnWrapper{
  13. Reader: link.Reader,
  14. Writer: link.Writer,
  15. Dest: destination,
  16. Conn: inboundConn,
  17. }
  18. return ReturnError(bufio.CopyPacketConn(ctx, conn, bufio.NewPacketConn(serverConn)))
  19. }
  20. type PacketConnWrapper struct {
  21. buf.Reader
  22. buf.Writer
  23. net.Conn
  24. Dest net.Destination
  25. cached buf.MultiBuffer
  26. }
  27. func (w *PacketConnWrapper) ReadPacket(buffer *B.Buffer) (M.Socksaddr, error) {
  28. if w.cached != nil {
  29. mb, bb := buf.SplitFirst(w.cached)
  30. if bb == nil {
  31. w.cached = nil
  32. } else {
  33. buffer.Write(bb.Bytes())
  34. w.cached = mb
  35. var destination net.Destination
  36. if bb.UDP != nil {
  37. destination = *bb.UDP
  38. } else {
  39. destination = w.Dest
  40. }
  41. bb.Release()
  42. return ToSocksaddr(destination), nil
  43. }
  44. }
  45. mb, err := w.ReadMultiBuffer()
  46. if err != nil {
  47. return M.Socksaddr{}, err
  48. }
  49. nb, bb := buf.SplitFirst(mb)
  50. if bb == nil {
  51. return M.Socksaddr{}, nil
  52. } else {
  53. buffer.Write(bb.Bytes())
  54. w.cached = nb
  55. var destination net.Destination
  56. if bb.UDP != nil {
  57. destination = *bb.UDP
  58. } else {
  59. destination = w.Dest
  60. }
  61. bb.Release()
  62. return ToSocksaddr(destination), nil
  63. }
  64. }
  65. func (w *PacketConnWrapper) WritePacket(buffer *B.Buffer, destination M.Socksaddr) error {
  66. vBuf := buf.New()
  67. vBuf.Write(buffer.Bytes())
  68. endpoint := ToDestination(destination, net.Network_UDP)
  69. vBuf.UDP = &endpoint
  70. return w.Writer.WriteMultiBuffer(buf.MultiBuffer{vBuf})
  71. }
  72. func (w *PacketConnWrapper) Close() error {
  73. buf.ReleaseMulti(w.cached)
  74. return nil
  75. }