hysteria/app/internal/forwarding/tcp.go
2023-07-02 15:40:16 -07:00

62 lines
1 KiB
Go

package forwarding
import (
"io"
"net"
"github.com/apernet/hysteria/core/client"
)
type TCPTunnel struct {
HyClient client.Client
Remote string
EventLogger TCPEventLogger
}
type TCPEventLogger interface {
Connect(addr net.Addr)
Error(addr net.Addr, err error)
}
func (t *TCPTunnel) Serve(listener net.Listener) error {
for {
conn, err := listener.Accept()
if err != nil {
return err
}
go t.handle(conn)
}
}
func (t *TCPTunnel) handle(conn net.Conn) {
defer conn.Close()
if t.EventLogger != nil {
t.EventLogger.Connect(conn.RemoteAddr())
}
var closeErr error
defer func() {
if t.EventLogger != nil {
t.EventLogger.Error(conn.RemoteAddr(), closeErr)
}
}()
rc, err := t.HyClient.DialTCP(t.Remote)
if err != nil {
closeErr = err
return
}
defer rc.Close()
// Start forwarding
copyErrChan := make(chan error, 2)
go func() {
_, copyErr := io.Copy(rc, conn)
copyErrChan <- copyErr
}()
go func() {
_, copyErr := io.Copy(conn, rc)
copyErrChan <- copyErr
}()
closeErr = <-copyErrChan
}