copy.go 865 B

12345678910111213141516171819202122232425262728293031323334353637
  1. package tunnel
  2. import (
  3. "context"
  4. "net"
  5. "runtime"
  6. "time"
  7. "github.com/sagernet/sing/common"
  8. "github.com/sagernet/sing/common/buf"
  9. "github.com/sagernet/sing/common/bufio"
  10. E "github.com/sagernet/sing/common/exceptions"
  11. )
  12. func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) error {
  13. _payload := buf.StackNew()
  14. payload := common.Dup(_payload)
  15. err := conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
  16. if err != nil {
  17. return err
  18. }
  19. _, err = payload.ReadFrom(conn)
  20. if err != nil && !E.IsTimeout(err) {
  21. return E.Cause(err, "read payload")
  22. }
  23. err = conn.SetReadDeadline(time.Time{})
  24. if err != nil {
  25. payload.Release()
  26. return err
  27. }
  28. _, err = serverConn.Write(payload.Bytes())
  29. if err != nil {
  30. return E.Cause(err, "client handshake")
  31. }
  32. runtime.KeepAlive(_payload)
  33. return bufio.CopyConn(ctx, conn, serverConn)
  34. }