router: router.id is optional
This commit is contained in:
@@ -90,9 +90,11 @@ func (c *routerConnector) Connect(ctx context.Context, conn net.Conn, network, a
|
|||||||
af.ParseFrom(address)
|
af.ParseFrom(address)
|
||||||
req.Features = append(req.Features, af) // dst address
|
req.Features = append(req.Features, af) // dst address
|
||||||
|
|
||||||
|
if !c.md.routerID.IsZero() {
|
||||||
req.Features = append(req.Features, &relay.TunnelFeature{
|
req.Features = append(req.Features, &relay.TunnelFeature{
|
||||||
ID: c.md.routerID,
|
ID: c.md.routerID,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := req.WriteTo(conn); err != nil {
|
if _, err := req.WriteTo(conn); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -30,13 +30,5 @@ func (c *routerConnector) parseMetadata(md mdata.Metadata) (err error) {
|
|||||||
c.md.routerID = relay.NewTunnelID(uuid[:])
|
c.md.routerID = relay.NewTunnelID(uuid[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.md.routerID.IsZero() {
|
|
||||||
uuid, err := uuid.NewUUID()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.md.routerID = relay.NewTunnelID(uuid[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-12
@@ -10,6 +10,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/core/common/bufpool"
|
"github.com/go-gost/core/common/bufpool"
|
||||||
"github.com/go-gost/core/limiter"
|
"github.com/go-gost/core/limiter"
|
||||||
@@ -48,7 +49,7 @@ func (h *routerHandler) handleAssociate(ctx context.Context, conn net.Conn, netw
|
|||||||
rid = parseRouterID(rule.Endpoint)
|
rid = parseRouterID(rule.Endpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rid.IsZero() || !rid.Equal(routerID) {
|
if !rid.Equal(routerID) {
|
||||||
resp.Status = relay.StatusHostUnreachable
|
resp.Status = relay.StatusHostUnreachable
|
||||||
resp.WriteTo(conn)
|
resp.WriteTo(conn)
|
||||||
err := fmt.Errorf("no route to host %s", host)
|
err := fmt.Errorf("no route to host %s", host)
|
||||||
@@ -111,13 +112,19 @@ func (h *routerHandler) handleAssociate(ctx context.Context, conn net.Conn, netw
|
|||||||
Name: clientID,
|
Name: clientID,
|
||||||
Node: h.id,
|
Node: h.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
go h.sdRenew(ctx, clientID, connectorID.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("%s/%s: router=%s, connector=%s, weight=%d established", host, network, routerID, connectorID, connectorID.Weight())
|
log.Debugf("%s/%s: router=%s, connector=%s, weight=%d established", host, network, routerID, connectorID, connectorID.Weight())
|
||||||
|
|
||||||
for {
|
|
||||||
b := bufpool.Get(h.md.bufferSize)
|
b := bufpool.Get(h.md.bufferSize)
|
||||||
|
defer bufpool.Put(b)
|
||||||
|
|
||||||
|
for {
|
||||||
n, err := conn.Read(b)
|
n, err := conn.Read(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
@@ -130,9 +137,25 @@ func (h *routerHandler) handleAssociate(ctx context.Context, conn net.Conn, netw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *routerHandler) handlePacket(ctx context.Context, data []byte, routerID relay.TunnelID, log logger.Logger) error {
|
func (h *routerHandler) sdRenew(ctx context.Context, clientID string, connectorID string) {
|
||||||
defer bufpool.Put(data)
|
tc := time.NewTicker(h.md.sdRenewInterval)
|
||||||
|
defer tc.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-tc.C:
|
||||||
|
h.md.sd.Renew(ctx, &sd.Service{
|
||||||
|
ID: connectorID,
|
||||||
|
Name: clientID,
|
||||||
|
Node: h.id,
|
||||||
|
})
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *routerHandler) handlePacket(ctx context.Context, data []byte, routerID relay.TunnelID, log logger.Logger) error {
|
||||||
var dstIP net.IP
|
var dstIP net.IP
|
||||||
if waterutil.IsIPv4(data) {
|
if waterutil.IsIPv4(data) {
|
||||||
header, err := ipv4.ParseHeader(data)
|
header, err := ipv4.ParseHeader(data)
|
||||||
@@ -167,16 +190,10 @@ func (h *routerHandler) handlePacket(ctx context.Context, data []byte, routerID
|
|||||||
|
|
||||||
rid := routerID.String()
|
rid := routerID.String()
|
||||||
|
|
||||||
var route *router.Route
|
route := h.getRoute(ctx, rid, dstIP.String())
|
||||||
if r := registry.RouterRegistry().Get(rid); r != nil {
|
|
||||||
route = r.GetRoute(ctx, dstIP.String(), router.IDOption(rid))
|
|
||||||
}
|
|
||||||
if route == nil && h.md.router != nil {
|
|
||||||
route = h.md.router.GetRoute(ctx, dstIP.String(), router.IDOption(rid))
|
|
||||||
}
|
|
||||||
if route == nil || route.Gateway == "" {
|
if route == nil || route.Gateway == "" {
|
||||||
// no route to host, discard
|
// no route to host, discard
|
||||||
return fmt.Errorf("route to host %s", dstIP)
|
return fmt.Errorf("no route to host %s", dstIP)
|
||||||
}
|
}
|
||||||
|
|
||||||
if log.IsLevelEnabled(logger.TraceLevel) {
|
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||||
@@ -218,6 +235,28 @@ func (h *routerHandler) handlePacket(ctx context.Context, data []byte, routerID
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *routerHandler) getRoute(ctx context.Context, rid string, dst string) *router.Route {
|
||||||
|
if h.md.routerCacheEnabled {
|
||||||
|
if item := h.routeCache.Get(dst); item != nil && !item.Expired() {
|
||||||
|
v, _ := item.Value().(*router.Route)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var route *router.Route
|
||||||
|
if r := registry.RouterRegistry().Get(rid); r != nil {
|
||||||
|
route = r.GetRoute(ctx, dst, router.IDOption(rid))
|
||||||
|
}
|
||||||
|
if route == nil && h.md.router != nil {
|
||||||
|
route = h.md.router.GetRoute(ctx, dst, router.IDOption(rid))
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.md.routerCacheEnabled {
|
||||||
|
h.routeCache.Set(dst, cache.NewItem(route, h.md.routerCacheExpiration))
|
||||||
|
}
|
||||||
|
return route
|
||||||
|
}
|
||||||
|
|
||||||
func (h *routerHandler) getAddrforRoute(ctx context.Context, routerID, gateway string) net.Addr {
|
func (h *routerHandler) getAddrforRoute(ctx context.Context, routerID, gateway string) net.Addr {
|
||||||
if h.md.sd == nil {
|
if h.md.sd == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ type routerHandler struct {
|
|||||||
limiter traffic.TrafficLimiter
|
limiter traffic.TrafficLimiter
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
sdCache *cache.Cache
|
sdCache *cache.Cache
|
||||||
|
routeCache *cache.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
@@ -58,6 +59,7 @@ func NewHandler(opts ...handler.Option) handler.Handler {
|
|||||||
return &routerHandler{
|
return &routerHandler{
|
||||||
options: options,
|
options: options,
|
||||||
sdCache: cache.NewCache(time.Minute),
|
sdCache: cache.NewCache(time.Minute),
|
||||||
|
routeCache: cache.NewCache(time.Minute),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,12 +205,6 @@ func (h *routerHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if routerID.IsZero() {
|
|
||||||
resp.Status = relay.StatusBadRequest
|
|
||||||
resp.WriteTo(conn)
|
|
||||||
return ErrRouterID
|
|
||||||
}
|
|
||||||
|
|
||||||
if user != "" {
|
if user != "" {
|
||||||
log = log.WithFields(map[string]any{"user": user})
|
log = log.WithFields(map[string]any{"user": user})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ type metadata struct {
|
|||||||
ingress ingress.Ingress
|
ingress ingress.Ingress
|
||||||
sd sd.SD
|
sd sd.SD
|
||||||
sdCacheExpiration time.Duration
|
sdCacheExpiration time.Duration
|
||||||
|
sdRenewInterval time.Duration
|
||||||
|
|
||||||
router router.Router
|
router router.Router
|
||||||
|
routerCacheEnabled bool
|
||||||
|
routerCacheExpiration time.Duration
|
||||||
|
|
||||||
observerPeriod time.Duration
|
observerPeriod time.Duration
|
||||||
observerResetTraffic bool
|
observerResetTraffic bool
|
||||||
@@ -45,12 +49,21 @@ func (h *routerHandler) parseMetadata(md mdata.Metadata) (err error) {
|
|||||||
h.md.ingress = registry.IngressRegistry().Get(mdutil.GetString(md, "ingress"))
|
h.md.ingress = registry.IngressRegistry().Get(mdutil.GetString(md, "ingress"))
|
||||||
|
|
||||||
h.md.sd = registry.SDRegistry().Get(mdutil.GetString(md, "sd"))
|
h.md.sd = registry.SDRegistry().Get(mdutil.GetString(md, "sd"))
|
||||||
h.md.sdCacheExpiration = mdutil.GetDuration(md, "sd.cacheExpiration")
|
h.md.sdCacheExpiration = mdutil.GetDuration(md, "sd.cache.expiration")
|
||||||
if h.md.sdCacheExpiration <= 0 {
|
if h.md.sdCacheExpiration <= 0 {
|
||||||
h.md.sdCacheExpiration = defaultCacheExpiration
|
h.md.sdCacheExpiration = defaultCacheExpiration
|
||||||
}
|
}
|
||||||
|
h.md.sdRenewInterval = mdutil.GetDuration(md, "sd.renewInterval")
|
||||||
|
if h.md.sdRenewInterval < time.Second {
|
||||||
|
h.md.sdRenewInterval = defaultTTL
|
||||||
|
}
|
||||||
|
|
||||||
h.md.router = registry.RouterRegistry().Get(mdutil.GetString(md, "router"))
|
h.md.router = registry.RouterRegistry().Get(mdutil.GetString(md, "router"))
|
||||||
|
h.md.routerCacheEnabled = mdutil.GetBool(md, "router.cache")
|
||||||
|
h.md.routerCacheExpiration = mdutil.GetDuration(md, "router.cache.expiration")
|
||||||
|
if h.md.routerCacheExpiration <= 0 {
|
||||||
|
h.md.routerCacheExpiration = defaultCacheExpiration
|
||||||
|
}
|
||||||
|
|
||||||
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
|
h.md.observerPeriod = mdutil.GetDuration(md, "observePeriod", "observer.period", "observer.observePeriod")
|
||||||
if h.md.observerPeriod == 0 {
|
if h.md.observerPeriod == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user