hysteria/core/server/copy.go

59 lines
1.3 KiB
Go

package server
import "io"
func copyBufferLog(dst io.Writer, src io.Reader, log func(n uint64)) error {
buf := make([]byte, 32*1024)
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
log(uint64(nw))
}
if ew != nil {
return ew
}
}
if er != nil {
if er == io.EOF {
// EOF should not be considered as an error
return nil
}
return er
}
}
}
func copyTwoWayWithLogger(id string, serverRw, remoteRw io.ReadWriter, l TrafficLogger) error {
errChan := make(chan error, 2)
go func() {
errChan <- copyBufferLog(serverRw, remoteRw, func(n uint64) {
l.Log(id, 0, n)
})
}()
go func() {
errChan <- copyBufferLog(remoteRw, serverRw, func(n uint64) {
l.Log(id, n, 0)
})
}()
// Block until one of the two goroutines returns
return <-errChan
}
// copyTwoWay is the "fast-path" version of copyTwoWayWithLogger that does not log traffic.
// It uses the built-in io.Copy instead of our own copyBufferLog.
func copyTwoWay(serverRw, remoteRw io.ReadWriter) error {
errChan := make(chan error, 2)
go func() {
_, err := io.Copy(serverRw, remoteRw)
errChan <- err
}()
go func() {
_, err := io.Copy(remoteRw, serverRw)
errChan <- err
}()
// Block until one of the two goroutines returns
return <-errChan
}