nip/internal/forward/forward.go

60 lines
985 B
Go

package forward
import (
"errors"
"io"
"net"
"git.lovezsh.com/lovezsh/nip/internal/pkg/encoding"
"git.lovezsh.com/lovezsh/nip/internal/proto"
)
type Forwarder interface {
Forward(net.Conn, string) (err error)
}
type forwarder struct {
server string
token string
}
func New(server string, token string) Forwarder {
return &forwarder{server, token}
}
func (f *forwarder) Forward(src net.Conn, target string) (err error) {
dst, err := net.Dial("tcp", f.server)
if err != nil {
return err
}
defer dst.Close()
req := proto.Request{
Target: target,
Token: f.token,
}
if err = encoding.NewEncoder(dst).Encode(&req); err != nil {
return
}
var resp proto.Response
if err = encoding.NewDecoder(dst).Decode(&resp); err != nil {
return
}
if resp.Code != 0 {
return errors.New(resp.Message)
}
ch := make(chan error)
go func() {
_, err := io.Copy(dst, src)
ch <- err
}()
go func() {
_, err := io.Copy(src, dst)
ch <- err
}()
return <-ch
}