add unix/serial dialer and connector

This commit is contained in:
ginuerzh 2023-09-18 23:14:55 +08:00
parent b720e72870
commit 95da26cf49
9 changed files with 288 additions and 56 deletions

View File

@ -0,0 +1,45 @@
package serial
import (
"context"
"net"
"github.com/go-gost/core/connector"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/x/registry"
)
func init() {
registry.ConnectorRegistry().Register("serial", NewConnector)
}
type serialConnector struct {
options connector.Options
}
func NewConnector(opts ...connector.Option) connector.Connector {
options := connector.Options{}
for _, opt := range opts {
opt(&options)
}
return &serialConnector{
options: options,
}
}
func (c *serialConnector) Init(md md.Metadata) (err error) {
return nil
}
func (c *serialConnector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) {
log := c.options.Logger.WithFields(map[string]any{
"remote": conn.RemoteAddr().String(),
"local": conn.LocalAddr().String(),
"network": network,
"address": address,
})
log.Debugf("connect %s/%s", address, network)
return conn, nil
}

View File

@ -0,0 +1,45 @@
package tcp
import (
"context"
"net"
"github.com/go-gost/core/connector"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/x/registry"
)
func init() {
registry.ConnectorRegistry().Register("tcp", NewConnector)
}
type tcpConnector struct {
options connector.Options
}
func NewConnector(opts ...connector.Option) connector.Connector {
options := connector.Options{}
for _, opt := range opts {
opt(&options)
}
return &tcpConnector{
options: options,
}
}
func (c *tcpConnector) Init(md md.Metadata) (err error) {
return nil
}
func (c *tcpConnector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) {
log := c.options.Logger.WithFields(map[string]any{
"remote": conn.RemoteAddr().String(),
"local": conn.LocalAddr().String(),
"network": network,
"address": address,
})
log.Debugf("connect %s/%s", address, network)
return conn, nil
}

View File

@ -0,0 +1,45 @@
package unix
import (
"context"
"net"
"github.com/go-gost/core/connector"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/x/registry"
)
func init() {
registry.ConnectorRegistry().Register("unix", NewConnector)
}
type unixConnector struct {
options connector.Options
}
func NewConnector(opts ...connector.Option) connector.Connector {
options := connector.Options{}
for _, opt := range opts {
opt(&options)
}
return &unixConnector{
options: options,
}
}
func (c *unixConnector) Init(md md.Metadata) (err error) {
return nil
}
func (c *unixConnector) Connect(ctx context.Context, conn net.Conn, network, address string, opts ...connector.ConnectOption) (net.Conn, error) {
log := c.options.Logger.WithFields(map[string]any{
"remote": conn.RemoteAddr().String(),
"local": conn.LocalAddr().String(),
"network": network,
"address": address,
})
log.Debugf("connect %s/%s", address, network)
return conn, nil
}

52
dialer/serial/dialer.go Normal file
View File

@ -0,0 +1,52 @@
package serial
import (
"context"
"net"
"github.com/go-gost/core/dialer"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
serial_util "github.com/go-gost/x/internal/util/serial"
"github.com/go-gost/x/registry"
goserial "github.com/tarm/serial"
)
func init() {
registry.DialerRegistry().Register("serial", NewDialer)
}
type serialDialer struct {
md metadata
logger logger.Logger
}
func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{}
for _, opt := range opts {
opt(options)
}
return &serialDialer{
logger: options.Logger,
}
}
func (d *serialDialer) Init(md md.Metadata) (err error) {
return d.parseMetadata(md)
}
func (d *serialDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOption) (net.Conn, error) {
var options dialer.DialOptions
for _, opt := range opts {
opt(&options)
}
cfg := serial_util.ParseConfigFromAddr(addr)
port, err := goserial.OpenPort(cfg)
if err != nil {
return nil, err
}
return serial_util.NewConn(port, &serial_util.Addr{Port: cfg.Name}, nil), nil
}

12
dialer/serial/metadata.go Normal file
View File

@ -0,0 +1,12 @@
package serial
import (
md "github.com/go-gost/core/metadata"
)
type metadata struct {
}
func (d *serialDialer) parseMetadata(md md.Metadata) (err error) {
return
}

48
dialer/unix/dialer.go Normal file
View File

@ -0,0 +1,48 @@
package unix
import (
"context"
"net"
"github.com/go-gost/core/dialer"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/x/registry"
)
func init() {
registry.DialerRegistry().Register("unix", NewDialer)
}
type unixDialer struct {
md metadata
logger logger.Logger
}
func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{}
for _, opt := range opts {
opt(options)
}
return &unixDialer{
logger: options.Logger,
}
}
func (d *unixDialer) Init(md md.Metadata) (err error) {
return d.parseMetadata(md)
}
func (d *unixDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOption) (net.Conn, error) {
var options dialer.DialOptions
for _, opt := range opts {
opt(&options)
}
conn, err := (&net.Dialer{}).DialContext(ctx, "unix", addr)
if err != nil {
d.logger.Error(err)
}
return conn, err
}

12
dialer/unix/metadata.go Normal file
View File

@ -0,0 +1,12 @@
package unix
import (
md "github.com/go-gost/core/metadata"
)
type metadata struct {
}
func (d *unixDialer) parseMetadata(md md.Metadata) (err error) {
return
}

View File

@ -78,58 +78,44 @@ func (h *serialHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl
"local": conn.LocalAddr().String(),
})
var target *chain.Node
if h.hop != nil {
target = h.hop.Select(ctx)
}
if target == nil {
err := errors.New("target not available")
log.Error(err)
return err
}
log = log.WithFields(map[string]any{
"node": target.Name,
"dst": target.Addr,
})
log.Debugf("%s >> %s", conn.LocalAddr(), target.Addr)
conn = &recorderConn{
Conn: conn,
recorder: h.recorder,
}
// serial port
if _, _, err := net.SplitHostPort(target.Addr); err != nil {
if h.hop != nil {
target := h.hop.Select(ctx)
if target == nil {
err := errors.New("target not available")
log.Error(err)
return err
}
log = log.WithFields(map[string]any{
"node": target.Name,
"dst": target.Addr,
})
return h.forwardSerial(ctx, conn, target, log)
}
cc, err := h.router.Dial(ctx, "tcp", target.Addr)
cc, err := h.router.Dial(ctx, "tcp", "@")
if err != nil {
log.Error(err)
if marker := target.Marker(); marker != nil {
marker.Mark()
}
return err
}
defer cc.Close()
if marker := target.Marker(); marker != nil {
marker.Reset()
}
t := time.Now()
log.Infof("%s <-> %s", conn.LocalAddr(), target.Addr)
log.Infof("%s <-> %s", conn.LocalAddr(), "@")
xnet.Transport(conn, cc)
log.WithFields(map[string]any{
"duration": time.Since(t),
}).Infof("%s >-< %s", conn.LocalAddr(), target.Addr)
}).Infof("%s >-< %s", conn.LocalAddr(), "@")
return nil
}
func (h *serialHandler) forwardSerial(ctx context.Context, conn net.Conn, target *chain.Node, log logger.Logger) (err error) {
log.Debugf("%s >> %s", conn.LocalAddr(), target.Addr)
var port io.ReadWriteCloser
cfg := serial_util.ParseConfigFromAddr(conn.LocalAddr().String())

View File

@ -65,52 +65,39 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
"local": conn.LocalAddr().String(),
})
var target *chain.Node
if h.hop != nil {
target = h.hop.Select(ctx)
}
if target == nil {
err := errors.New("target not available")
log.Error(err)
return err
}
log = log.WithFields(map[string]any{
"node": target.Name,
"dst": target.Addr,
})
log.Debugf("%s >> %s", conn.LocalAddr(), target.Addr)
if _, _, err := net.SplitHostPort(target.Addr); err != nil {
target := h.hop.Select(ctx)
if target == nil {
err := errors.New("target not available")
log.Error(err)
return err
}
log = log.WithFields(map[string]any{
"node": target.Name,
"dst": target.Addr,
})
return h.forwardUnix(ctx, conn, target, log)
}
cc, err := h.router.Dial(ctx, "tcp", target.Addr)
cc, err := h.router.Dial(ctx, "tcp", "@")
if err != nil {
log.Error(err)
if marker := target.Marker(); marker != nil {
marker.Mark()
}
return err
}
defer cc.Close()
if marker := target.Marker(); marker != nil {
marker.Reset()
}
t := time.Now()
log.Infof("%s <-> %s", conn.LocalAddr(), target.Addr)
log.Infof("%s <-> %s", conn.LocalAddr(), "@")
xnet.Transport(conn, cc)
log.WithFields(map[string]any{
"duration": time.Since(t),
}).Infof("%s >-< %s", conn.LocalAddr(), target.Addr)
}).Infof("%s >-< %s", conn.LocalAddr(), "@")
return nil
}
func (h *unixHandler) forwardUnix(ctx context.Context, conn net.Conn, target *chain.Node, log logger.Logger) (err error) {
log.Debugf("%s >> %s", conn.LocalAddr(), target.Addr)
var cc io.ReadWriteCloser
if opts := h.router.Options(); opts != nil && opts.Chain != nil {