x/handler/tunnel/dialer.go
2023-11-02 22:31:52 +08:00

79 lines
1.2 KiB
Go

package tunnel
import (
"context"
"net"
"time"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/sd"
)
type Dialer struct {
node string
pool *ConnectorPool
sd sd.SD
retry int
timeout time.Duration
log logger.Logger
}
func (d *Dialer) Dial(ctx context.Context, network string, tid string) (conn net.Conn, node string, cid string, err error) {
retry := d.retry
if retry <= 0 {
retry = 1
}
for i := 0; i < retry; i++ {
c := d.pool.Get(network, tid)
if c == nil {
break
}
conn, err = c.Session().GetConn()
if err != nil {
d.log.Error(err)
continue
}
node = d.node
cid = c.id.String()
break
}
if conn != nil || err != nil {
return
}
if d.sd == nil {
err = ErrTunnelNotAvailable
return
}
ss, err := d.sd.Get(ctx, tid)
if err != nil {
return
}
var service *sd.Service
for _, s := range ss {
d.log.Debugf("%+v", s)
if s.Name != d.node && s.Network == network {
service = s
break
}
}
if service == nil || service.Address == "" {
err = ErrTunnelNotAvailable
return
}
node = service.Node
cid = service.Name
dialer := net.Dialer{
Timeout: d.timeout,
}
conn, err = dialer.DialContext(ctx, network, service.Address)
return
}