Skip to content

Commit

Permalink
cs: enable v2 beaconing through feature flag
Browse files Browse the repository at this point in the history
Create v2 path segment extender if feature flag is set.
Construct v2 paths for registering down paths if feature flag is set.
  • Loading branch information
oncilla committed Jun 30, 2020
1 parent 93f1d1c commit f9da520
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 80 deletions.
2 changes: 1 addition & 1 deletion go/cs/beaconing/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ go_library(
"//go/lib/serrors:go_default_library",
"//go/lib/slayers/path:go_default_library",
"//go/lib/snet:go_default_library",
"//go/lib/snet/addrutil:go_default_library",
"//go/lib/spath:go_default_library",
"//go/lib/topology:go_default_library",
"//go/lib/util:go_default_library",
Expand Down Expand Up @@ -71,6 +70,7 @@ go_test(
"//go/lib/scrypto/cppki:go_default_library",
"//go/lib/serrors:go_default_library",
"//go/lib/snet:go_default_library",
"//go/lib/snet/addrutil:go_default_library",
"//go/lib/spath:go_default_library",
"//go/lib/topology:go_default_library",
"//go/lib/util:go_default_library",
Expand Down
31 changes: 17 additions & 14 deletions go/cs/beaconing/registrar.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/scionproto/scion/go/lib/infra/modules/seghandler"
"github.com/scionproto/scion/go/lib/log"
"github.com/scionproto/scion/go/lib/periodic"
"github.com/scionproto/scion/go/lib/snet/addrutil"
"github.com/scionproto/scion/go/lib/topology"
"github.com/scionproto/scion/go/proto"
)
Expand All @@ -51,6 +50,11 @@ type RPC interface {
RegisterSegment(ctx context.Context, meta seg.Meta, remote net.Addr) error
}

// Pather computes the remote address with a path based on the provided segment.
type Pather interface {
GetPath(svc addr.HostSVC, ps *seg.PathSegment) (net.Addr, error)
}

var _ periodic.Task = (*Registrar)(nil)

// Registrar is used to periodically register path segments with the appropriate
Expand All @@ -61,13 +65,12 @@ type Registrar struct {
Provider SegmentProvider
Store SegmentStore
RPC RPC
Pather Pather
IA addr.IA
Signer ctrl.Signer
Intfs *ifstate.Interfaces
Type proto.PathSegType

TopoProvider topology.Provider // FIXME(roosd): reduce this to the minimal required interface.

// tick is mutable.
Tick Tick
lastSucc time.Time
Expand Down Expand Up @@ -134,11 +137,11 @@ func (r *Registrar) registerRemote(ctx context.Context, segments <-chan beacon.B
}
expected++
s := remoteRegistrar{
segType: r.Type,
rpc: r.RPC,
topoProvider: r.TopoProvider,
summary: s,
wg: &wg,
segType: r.Type,
rpc: r.RPC,
pather: r.Pather,
summary: s,
wg: &wg,
}

// Avoid head-of-line blocking when sending message to slow servers.
Expand Down Expand Up @@ -210,18 +213,18 @@ func (r *Registrar) logSummary(logger log.Logger, s *summary) {

// remoteRegistrar registers one segment with the path server.
type remoteRegistrar struct {
segType proto.PathSegType
rpc RPC
topoProvider topology.Provider
summary *summary
wg *sync.WaitGroup
segType proto.PathSegType
rpc RPC
pather Pather
summary *summary
wg *sync.WaitGroup
}

// start extends the beacon and starts a go routine that registers the beacon
// with the path server.
func (r *remoteRegistrar) start(ctx context.Context, bseg beacon.Beacon) {
logger := log.FromCtx(ctx)
addr, err := addrutil.GetPath(addr.SvcPS, bseg.Segment, r.topoProvider)
addr, err := r.pather.GetPath(addr.SvcPS, bseg.Segment)
if err != nil {
metrics.Registrar.InternalErrorsWithType(r.segType.String()).Inc()
logger.Error("[beaconing.Registrar] Unable to choose server", "err", err)
Expand Down
63 changes: 32 additions & 31 deletions go/cs/beaconing/registrar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"github.com/scionproto/scion/go/lib/scrypto"
"github.com/scionproto/scion/go/lib/scrypto/cppki"
"github.com/scionproto/scion/go/lib/snet"
"github.com/scionproto/scion/go/lib/snet/addrutil"
"github.com/scionproto/scion/go/lib/xtest/graph"
"github.com/scionproto/scion/go/pkg/trust"
"github.com/scionproto/scion/go/proto"
Expand Down Expand Up @@ -102,14 +103,14 @@ func TestRegistrarRun(t *testing.T) {
MaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime),
StaticInfo: func() *StaticInfoCfg { return nil },
},
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
Store: segStore,
TopoProvider: topoProvider,
Type: test.segType,
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
Store: segStore,
Pather: addrutil.LegacyPather{TopoProvider: topoProvider},
Type: test.segType,
}
g := graph.NewDefaultGraph(mctrl)
segProvider.EXPECT().SegmentsToRegister(gomock.Any(), test.segType).DoAndReturn(
Expand Down Expand Up @@ -188,14 +189,14 @@ func TestRegistrarRun(t *testing.T) {
MaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime),
StaticInfo: func() *StaticInfoCfg { return nil },
},
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
TopoProvider: topoProvider,
Type: test.segType,
RPC: rpc,
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
Pather: addrutil.LegacyPather{TopoProvider: topoProvider},
Type: test.segType,
RPC: rpc,
}
g := graph.NewDefaultGraph(mctrl)
segProvider.EXPECT().SegmentsToRegister(gomock.Any(), test.segType).DoAndReturn(
Expand Down Expand Up @@ -279,13 +280,13 @@ func TestRegistrarRun(t *testing.T) {
MaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime),
StaticInfo: func() *StaticInfoCfg { return nil },
},
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
TopoProvider: topoProvider,
Type: proto.PathSegType_core,
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
Pather: addrutil.LegacyPather{TopoProvider: topoProvider},
Type: proto.PathSegType_core,
}
res := make(chan beacon.BeaconOrErr, 3)
segProvider.EXPECT().SegmentsToRegister(gomock.Any(), proto.PathSegType_core).DoAndReturn(
Expand Down Expand Up @@ -322,14 +323,14 @@ func TestRegistrarRun(t *testing.T) {
MaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime),
StaticInfo: func() *StaticInfoCfg { return nil },
},
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
TopoProvider: topoProvider,
Type: proto.PathSegType_down,
RPC: rpc,
IA: topoProvider.Get().IA(),
Signer: testSigner(t, priv, topoProvider.Get().IA()),
Intfs: intfs,
Tick: NewTick(time.Hour),
Provider: segProvider,
Pather: addrutil.LegacyPather{TopoProvider: topoProvider},
Type: proto.PathSegType_down,
RPC: rpc,
}
g := graph.NewDefaultGraph(mctrl)
require.NoError(t, err)
Expand Down
2 changes: 2 additions & 0 deletions go/lib/snet/addrutil/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ go_library(
"//go/lib/common:go_default_library",
"//go/lib/ctrl/seg:go_default_library",
"//go/lib/serrors:go_default_library",
"//go/lib/slayers/path:go_default_library",
"//go/lib/slayers/path/scion:go_default_library",
"//go/lib/snet:go_default_library",
"//go/lib/spath:go_default_library",
"//go/lib/topology:go_default_library",
Expand Down
74 changes: 74 additions & 0 deletions go/lib/snet/addrutil/addrutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,91 @@ package addrutil

import (
"bytes"
"encoding/binary"
"net"

"github.com/scionproto/scion/go/lib/addr"
"github.com/scionproto/scion/go/lib/common"
"github.com/scionproto/scion/go/lib/ctrl/seg"
"github.com/scionproto/scion/go/lib/serrors"
"github.com/scionproto/scion/go/lib/slayers/path"
"github.com/scionproto/scion/go/lib/slayers/path/scion"
"github.com/scionproto/scion/go/lib/snet"
"github.com/scionproto/scion/go/lib/spath"
"github.com/scionproto/scion/go/lib/topology"
)

type Pather struct {
// UnderlayNextHop determines the next hop underlay address for the
// specified interface id.
UnderlayNextHop func(ifID uint16) (*net.UDPAddr, bool)
}

func (p Pather) GetPath(svc addr.HostSVC, ps *seg.PathSegment) (net.Addr, error) {
if len(ps.ASEntries) == 0 {
return nil, serrors.New("empty path")
}

beta := ps.SData.SegID
// The hop fields need to be in reversed order.
hopFields := make([]*path.HopField, len(ps.ASEntries))
for i, entry := range ps.ASEntries {
if len(entry.HopEntries) == 0 {
return nil, serrors.New("hop with no entry", "index", i)
}
hopFields[len(hopFields)-1-i] = &path.HopField{
ConsIngress: entry.HopEntries[0].HopField.ConsIngress,
ConsEgress: entry.HopEntries[0].HopField.ConsEgress,
ExpTime: entry.HopEntries[0].HopField.ExpTime,
Mac: entry.HopEntries[0].HopField.MAC,
}
beta = beta ^ binary.BigEndian.Uint16(entry.HopEntries[0].HopField.MAC[:2])
}

hops := len(hopFields) - 1
dec := scion.Decoded{
Base: scion.Base{
PathMeta: scion.MetaHdr{
CurrHF: 0,
CurrINF: 0,
SegLen: [3]uint8{uint8(hops), 0, 0},
},
NumHops: hops,
NumINF: 1,
},
InfoFields: []*path.InfoField{{
Timestamp: ps.SData.RawTimestamp,
ConsDir: false,
SegID: beta,
}},
HopFields: hopFields,
}
raw := make([]byte, dec.Len())
if err := dec.SerializeTo(raw); err != nil {
return nil, serrors.WrapStr("serializing path", err)
}
ifID := dec.HopFields[0].ConsIngress
nextHop, ok := p.UnderlayNextHop(ifID)
if !ok {
return nil, serrors.New("first-hop border router not found", "intf_id", ifID)
}
return &snet.SVCAddr{
IA: ps.FirstIA(),
Path: spath.NewV2(raw),
NextHop: nextHop,
SVC: svc,
}, nil

}

type LegacyPather struct {
TopoProvider topology.Provider
}

func (p LegacyPather) GetPath(svc addr.HostSVC, ps *seg.PathSegment) (net.Addr, error) {
return GetPath(svc, ps, p.TopoProvider)
}

// GetPath creates a path from the given segment and then creates a snet.SVCAddr.
func GetPath(svc addr.HostSVC, ps *seg.PathSegment, topoProv topology.Provider) (net.Addr, error) {
p, err := legacyPath(ps)
Expand Down
1 change: 1 addition & 0 deletions go/pkg/cs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ go_library(
"//go/lib/scrypto:go_default_library",
"//go/lib/serrors:go_default_library",
"//go/lib/snet:go_default_library",
"//go/lib/snet/addrutil:go_default_library",
"//go/lib/sock/reliable:go_default_library",
"//go/lib/sock/reliable/reconnect:go_default_library",
"//go/lib/spath:go_default_library",
Expand Down
Loading

0 comments on commit f9da520

Please sign in to comment.