github.com/yaling888/clash@v1.53.0/common/net/relay.go (about)

     1  package net
     2  
     3  import (
     4  	"io"
     5  	"net"
     6  	"time"
     7  
     8  	"github.com/yaling888/clash/common/pool"
     9  )
    10  
    11  // Relay copies between left and right bidirectionally.
    12  func Relay(leftConn, rightConn net.Conn) {
    13  	ch := make(chan error)
    14  
    15  	tcpKeepAlive(leftConn)
    16  	tcpKeepAlive(rightConn)
    17  
    18  	go func() {
    19  		bufP := pool.GetNetBuf()
    20  		defer pool.PutNetBuf(bufP)
    21  		_, err := io.CopyBuffer(WriteOnlyWriter{Writer: leftConn}, ReadOnlyReader{Reader: rightConn}, *bufP)
    22  		_ = leftConn.SetReadDeadline(time.Now())
    23  		ch <- err
    24  	}()
    25  
    26  	bufP := pool.GetNetBuf()
    27  	defer pool.PutNetBuf(bufP)
    28  	_, _ = io.CopyBuffer(WriteOnlyWriter{Writer: rightConn}, ReadOnlyReader{Reader: leftConn}, *bufP)
    29  	_ = rightConn.SetReadDeadline(time.Now())
    30  	<-ch
    31  }
    32  
    33  func tcpKeepAlive(c net.Conn) {
    34  	if tcp, ok := c.(*net.TCPConn); ok {
    35  		_ = tcp.SetKeepAlive(true)
    36  	}
    37  }