初版功能完成
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
// Package tcprelay performs protocol-agnostic TCP byte forwarding.
|
||||
package tcprelay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const bufferSize = 32 * 1024
|
||||
|
||||
var bufferPool = sync.Pool{New: func() any { return make([]byte, bufferSize) }}
|
||||
|
||||
// Relay copies both directions until EOF, cancellation, or an I/O failure.
|
||||
func Relay(ctx context.Context, left, right net.Conn) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
results := make(chan error, 2)
|
||||
copyDirection := func(destination, source net.Conn) {
|
||||
buffer := bufferPool.Get().([]byte)
|
||||
_, err := io.CopyBuffer(destination, source, buffer)
|
||||
bufferPool.Put(buffer)
|
||||
if closeWriter, ok := destination.(interface{ CloseWrite() error }); ok {
|
||||
_ = closeWriter.CloseWrite()
|
||||
}
|
||||
results <- err
|
||||
}
|
||||
go copyDirection(left, right)
|
||||
go copyDirection(right, left)
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
_ = left.Close()
|
||||
_ = right.Close()
|
||||
}()
|
||||
first := <-results
|
||||
cancel()
|
||||
_ = left.Close()
|
||||
_ = right.Close()
|
||||
second := <-results
|
||||
if first != nil && !errors.Is(first, net.ErrClosed) {
|
||||
return first
|
||||
}
|
||||
if second != nil && !errors.Is(second, net.ErrClosed) {
|
||||
return second
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user