diff --git a/go/beacon_srv/internal/beaconing/BUILD.bazel b/go/beacon_srv/internal/beaconing/BUILD.bazel index 09cec9b535..bf5f65419f 100644 --- a/go/beacon_srv/internal/beaconing/BUILD.bazel +++ b/go/beacon_srv/internal/beaconing/BUILD.bazel @@ -27,6 +27,7 @@ go_library( "//go/lib/ctrl/seg:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/messenger:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/infra/modules/segverifier:go_default_library", "//go/lib/log:go_default_library", "//go/lib/periodic:go_default_library", @@ -34,7 +35,6 @@ go_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", "//go/proto:go_default_library", ], @@ -63,6 +63,8 @@ go_test( "//go/lib/ctrl/seg:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/mock_infra:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", + "//go/lib/infra/modules/itopo/itopotest:go_default_library", "//go/lib/infra/modules/trust:go_default_library", "//go/lib/log:go_default_library", "//go/lib/overlay:go_default_library", diff --git a/go/beacon_srv/internal/beaconing/extender_test.go b/go/beacon_srv/internal/beaconing/extender_test.go index a8274a8dac..8175123e97 100644 --- a/go/beacon_srv/internal/beaconing/extender_test.go +++ b/go/beacon_srv/internal/beaconing/extender_test.go @@ -31,6 +31,7 @@ import ( "github.com/scionproto/scion/go/lib/ctrl" "github.com/scionproto/scion/go/lib/ctrl/seg" "github.com/scionproto/scion/go/lib/infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/infra/modules/trust" "github.com/scionproto/scion/go/lib/scrypto" "github.com/scionproto/scion/go/lib/spath" @@ -41,7 +42,7 @@ import ( ) func TestExtenderExtend(t *testing.T) { - topoProvider := xtest.TopoProviderFromFile(t, topoNonCore) + topoProvider := itopotest.TopoProviderFromFile(t, topoNonCore) mac, err := scrypto.InitMac(make(common.RawBytes, 16)) xtest.FailOnErr(t, err) pub, priv, err := scrypto.GenKeyPair(scrypto.Ed25519) @@ -112,13 +113,13 @@ func TestExtenderExtend(t *testing.T) { defer mctrl.Finish() g := graph.NewDefaultGraph(mctrl) // Setup interfaces with active parent, child and one peer interface. - intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, ifstate.Config{}) + intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}) intfs.Get(graph.If_111_B_120_X).Activate(graph.If_120_X_111_B) intfs.Get(graph.If_111_A_112_X).Activate(graph.If_112_X_111_A) intfs.Get(peer).Activate(graph.If_121_X_111_C) ext, err := ExtenderConf{ MTU: 1337, - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: mac, Intfs: intfs, GetMaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime), @@ -155,7 +156,7 @@ func TestExtenderExtend(t *testing.T) { SoMsg("TRCVer", entry.TrcVer, ShouldEqual, 84) SoMsg("IfIDSize", entry.IfIDSize, ShouldEqual, DefaultIfidSize) SoMsg("MTU", entry.MTU, ShouldEqual, 1337) - SoMsg("IA", entry.IA(), ShouldResemble, topoProvider.Get().ISD_AS) + SoMsg("IA", entry.IA(), ShouldResemble, topoProvider.Get().IA()) // Checks that inactive peers are ignored, even when provided. SoMsg("HopEntries length", len(entry.HopEntries), ShouldEqual, 2) }) @@ -184,12 +185,12 @@ func TestExtenderExtend(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() g := graph.NewDefaultGraph(mctrl) - intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, ifstate.Config{}) + intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}) xtest.FailOnErr(t, err) intfs.Get(graph.If_111_B_120_X).Activate(graph.If_120_X_111_B) ext, err := ExtenderConf{ MTU: 1337, - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: mac, GetMaxExpTime: maxExpTimeFactory(1), Intfs: intfs, @@ -207,11 +208,11 @@ func TestExtenderExtend(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() g := graph.NewDefaultGraph(mctrl) - intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, ifstate.Config{}) + intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}) xtest.FailOnErr(t, err) ext, err := ExtenderConf{ MTU: 1337, - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: mac, Intfs: intfs, GetMaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime), @@ -252,7 +253,7 @@ func TestExtenderExtend(t *testing.T) { Src: ctrl.SignSrcDef{ ChainVer: 42, TRCVer: 84, - IA: topoProvider.Get().ISD_AS, + IA: topoProvider.Get().IA(), }, Algo: scrypto.Ed25519, ExpTime: time.Now(), diff --git a/go/beacon_srv/internal/beaconing/handler_test.go b/go/beacon_srv/internal/beaconing/handler_test.go index 833c9afba8..05999f4b51 100644 --- a/go/beacon_srv/internal/beaconing/handler_test.go +++ b/go/beacon_srv/internal/beaconing/handler_test.go @@ -31,11 +31,12 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/seg" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/mock_infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/snet" "github.com/scionproto/scion/go/lib/spath" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/lib/xtest" "github.com/scionproto/scion/go/lib/xtest/graph" ) @@ -59,7 +60,7 @@ func TestNewHandler(t *testing.T) { pseg := testBeacon(g, []common.IFIDType{graph.If_220_X_120_B, graph.If_120_A_110_X}).Segment rw := mock_infra.NewMockResponseWriter(mctrl) rw.EXPECT().SendAckReply(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - topoProvider := xtest.TopoProviderFromFile(t, topoCore) + topoProvider := itopotest.TopoProviderFromFile(t, topoCore) t.Run("Correct beacon is inserted", func(t *testing.T) { inserter := mock_beaconing.NewMockBeaconInserter(mctrl) expectedBeacon := beacon.Beacon{Segment: pseg, InIfId: localIF} @@ -222,8 +223,8 @@ func testPath(ingressIfid common.IFIDType) *spath.Path { return path } -func testInterfaces(topo *topology.Topo) *ifstate.Interfaces { - intfs := ifstate.NewInterfaces(topo.IFInfoMap, ifstate.Config{}) +func testInterfaces(topo itopo.Topology) *ifstate.Interfaces { + intfs := ifstate.NewInterfaces(topo.IFInfoMap(), ifstate.Config{}) intfs.Get(graph.If_110_X_120_A).Activate(graph.If_120_A_110_X) return intfs } diff --git a/go/beacon_srv/internal/beaconing/originator_test.go b/go/beacon_srv/internal/beaconing/originator_test.go index cd1c711ddc..8728f94bf8 100644 --- a/go/beacon_srv/internal/beaconing/originator_test.go +++ b/go/beacon_srv/internal/beaconing/originator_test.go @@ -32,6 +32,7 @@ import ( "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/ctrl" "github.com/scionproto/scion/go/lib/ctrl/seg" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/overlay" "github.com/scionproto/scion/go/lib/scrypto" "github.com/scionproto/scion/go/lib/snet" @@ -47,20 +48,20 @@ const ( ) func TestOriginatorRun(t *testing.T) { - topoProvider := xtest.TopoProviderFromFile(t, topoCore) + topoProvider := itopotest.TopoProviderFromFile(t, topoCore) mac, err := scrypto.InitMac(make(common.RawBytes, 16)) xtest.FailOnErr(t, err) pub, priv, err := scrypto.GenKeyPair(scrypto.Ed25519) xtest.FailOnErr(t, err) - signer := testSigner(t, priv, topoProvider.Get().ISD_AS) + signer := testSigner(t, priv, topoProvider.Get().IA()) Convey("Run originates ifid packets on all active core and child interfaces", t, func() { mctrl := gomock.NewController(t) defer mctrl.Finish() - intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, ifstate.Config{}) + intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}) conn := mock_snet.NewMockPacketConn(mctrl) o, err := OriginatorConf{ Config: ExtenderConf{ - MTU: uint16(topoProvider.Get().MTU), + MTU: topoProvider.Get().MTU(), Signer: signer, Intfs: intfs, Mac: mac, @@ -101,7 +102,7 @@ func TestOriginatorRun(t *testing.T) { o.Run(nil) for i, msg := range msgs { Convey(fmt.Sprintf("Packet %d is correct", i), func() { - checkMsg(t, msg, pub, topoProvider.Get().IFInfoMap) + checkMsg(t, msg, pub, topoProvider.Get().IFInfoMap()) }) } // The second run should not cause any beacons to originate. @@ -110,11 +111,11 @@ func TestOriginatorRun(t *testing.T) { Convey("Fast recovery", t, func() { mctrl := gomock.NewController(t) defer mctrl.Finish() - intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, ifstate.Config{}) + intfs := ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}) conn := mock_snet.NewMockPacketConn(mctrl) o, err := OriginatorConf{ Config: ExtenderConf{ - MTU: uint16(topoProvider.Get().MTU), + MTU: topoProvider.Get().MTU(), Signer: signer, Intfs: intfs, Mac: mac, diff --git a/go/beacon_srv/internal/beaconing/propagator_test.go b/go/beacon_srv/internal/beaconing/propagator_test.go index 7a0a5988e6..a678f13268 100644 --- a/go/beacon_srv/internal/beaconing/propagator_test.go +++ b/go/beacon_srv/internal/beaconing/propagator_test.go @@ -30,6 +30,7 @@ import ( "github.com/scionproto/scion/go/beacon_srv/internal/onehop" "github.com/scionproto/scion/go/lib/addr" "github.com/scionproto/scion/go/lib/common" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/overlay" "github.com/scionproto/scion/go/lib/scrypto" "github.com/scionproto/scion/go/lib/snet" @@ -141,16 +142,16 @@ func TestPropagatorRun(t *testing.T) { Convey(test.name, t, func() { mctrl := gomock.NewController(t) defer mctrl.Finish() - topoProvider := xtest.TopoProviderFromFile(t, topoFile[test.core]) + topoProvider := itopotest.TopoProviderFromFile(t, topoFile[test.core]) provider := mock_beaconing.NewMockBeaconProvider(mctrl) conn := mock_snet.NewMockPacketConn(mctrl) cfg := PropagatorConf{ Config: ExtenderConf{ - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: macProp, - Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, + Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}), - MTU: uint16(topoProvider.Get().MTU), + MTU: topoProvider.Get().MTU(), GetMaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime), }, Period: time.Hour, @@ -158,7 +159,7 @@ func TestPropagatorRun(t *testing.T) { Core: test.core, BeaconSender: &onehop.BeaconSender{ Sender: onehop.Sender{ - IA: topoProvider.Get().ISD_AS, + IA: topoProvider.Get().IA(), Conn: conn, Addr: &addr.AppAddr{ L3: addr.HostFromIPStr("127.0.0.1"), @@ -203,7 +204,7 @@ func TestPropagatorRun(t *testing.T) { p.Run(nil) for i, msg := range msgs { Convey(fmt.Sprintf("Packet %d is correct", i), func() { - checkMsg(t, msg, pub, topoProvider.Get().IFInfoMap) + checkMsg(t, msg, pub, topoProvider.Get().IFInfoMap()) }) } // Check that no beacons are sent, since the period has not passed yet. @@ -213,16 +214,16 @@ func TestPropagatorRun(t *testing.T) { Convey("Fast recovery", t, func() { mctrl := gomock.NewController(t) defer mctrl.Finish() - topoProvider := xtest.TopoProviderFromFile(t, topoCore) + topoProvider := itopotest.TopoProviderFromFile(t, topoCore) provider := mock_beaconing.NewMockBeaconProvider(mctrl) conn := mock_snet.NewMockPacketConn(mctrl) cfg := PropagatorConf{ Config: ExtenderConf{ - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: macProp, - Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, + Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}), - MTU: uint16(topoProvider.Get().MTU), + MTU: uint16(topoProvider.Get().MTU()), GetMaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime), }, Period: 2 * time.Second, @@ -230,7 +231,7 @@ func TestPropagatorRun(t *testing.T) { Core: true, BeaconSender: &onehop.BeaconSender{ Sender: onehop.Sender{ - IA: topoProvider.Get().ISD_AS, + IA: topoProvider.Get().IA(), Conn: conn, Addr: &addr.AppAddr{ L3: addr.HostFromIPStr("127.0.0.1"), diff --git a/go/beacon_srv/internal/beaconing/registrar.go b/go/beacon_srv/internal/beaconing/registrar.go index 9acfca6737..0770d2067b 100644 --- a/go/beacon_srv/internal/beaconing/registrar.go +++ b/go/beacon_srv/internal/beaconing/registrar.go @@ -28,11 +28,11 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/seg" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/messenger" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/periodic" "github.com/scionproto/scion/go/lib/snet" "github.com/scionproto/scion/go/lib/snet/addrutil" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/proto" ) @@ -48,7 +48,7 @@ var _ periodic.Task = (*Registrar)(nil) type RegistrarConf struct { Config ExtenderConf SegProvider SegmentProvider - TopoProvider topology.Provider + TopoProvider itopo.ProviderI Msgr infra.Messenger Period time.Duration SegType proto.PathSegType @@ -61,7 +61,7 @@ type Registrar struct { *segExtender msgr infra.Messenger segProvider SegmentProvider - topoProvider topology.Provider + topoProvider itopo.ProviderI segType proto.PathSegType // mutable fields @@ -247,7 +247,7 @@ func (r *segmentRegistrar) onSuccess() { func (r *segmentRegistrar) chooseServer(pseg *seg.PathSegment) (net.Addr, error) { if r.segType != proto.PathSegType_down { topo := r.topoProvider.Get() - return &snet.Addr{IA: topo.ISD_AS, Host: addr.NewSVCUDPAppAddr(addr.SvcPS)}, nil + return &snet.Addr{IA: topo.IA(), Host: addr.NewSVCUDPAppAddr(addr.SvcPS)}, nil } return addrutil.GetPath(addr.SvcPS, pseg, r.topoProvider) } diff --git a/go/beacon_srv/internal/beaconing/registrar_test.go b/go/beacon_srv/internal/beaconing/registrar_test.go index d0b0adefc9..3d1b42d38d 100644 --- a/go/beacon_srv/internal/beaconing/registrar_test.go +++ b/go/beacon_srv/internal/beaconing/registrar_test.go @@ -35,6 +35,7 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/seg" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/mock_infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/infra/modules/trust" "github.com/scionproto/scion/go/lib/scrypto" "github.com/scionproto/scion/go/lib/snet" @@ -92,16 +93,16 @@ func TestRegistrarRun(t *testing.T) { Convey("Run registers a verifiable "+test.name+" to the correct path server", t, func() { mctrl := gomock.NewController(t) defer mctrl.Finish() - topoProvider := xtest.TopoProviderFromFile(t, test.fn) + topoProvider := itopotest.TopoProviderFromFile(t, test.fn) segProvider := mock_beaconing.NewMockSegmentProvider(mctrl) msgr := mock_infra.NewMockMessenger(mctrl) cfg := RegistrarConf{ Config: ExtenderConf{ - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: mac, - Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, + Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}), - MTU: uint16(topoProvider.Get().MTU), + MTU: topoProvider.Get().MTU(), GetMaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime), }, Period: time.Hour, @@ -163,7 +164,7 @@ func TestRegistrarRun(t *testing.T) { }) Convey(fmt.Sprintf("Segment %d is sent to the PS", segIdx), func() { if !test.remotePS { - SoMsg("IA", s.Addr.IA, ShouldResemble, topoProvider.Get().ISD_AS) + SoMsg("IA", s.Addr.IA, ShouldResemble, topoProvider.Get().IA()) a := addr.NewSVCUDPAppAddr(addr.SvcPS) SoMsg("Host", s.Addr.Host, ShouldResemble, a) return @@ -174,7 +175,7 @@ func TestRegistrarRun(t *testing.T) { SoMsg("err", err, ShouldBeNil) SoMsg("HopField", []uint8(hopF.Pack()), ShouldResemble, pseg.ASEntries[pseg.MaxAEIdx()].HopEntries[0].RawHopField) - a := topoProvider.Get().IFInfoMap[hopF.ConsIngress].InternalAddrs + a := topoProvider.Get().IFInfoMap()[hopF.ConsIngress].InternalAddrs SoMsg("Next", s.Addr.NextHop, ShouldResemble, a.PublicOverlay(a.Overlay)) }) } @@ -185,16 +186,16 @@ func TestRegistrarRun(t *testing.T) { Convey("Run drains the channel", t, func() { mctrl := gomock.NewController(t) defer mctrl.Finish() - topoProvider := xtest.TopoProviderFromFile(t, topoCore) + topoProvider := itopotest.TopoProviderFromFile(t, topoCore) segProvider := mock_beaconing.NewMockSegmentProvider(mctrl) msgr := mock_infra.NewMockMessenger(mctrl) cfg := RegistrarConf{ Config: ExtenderConf{ - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: mac, - Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, + Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}), - MTU: uint16(topoProvider.Get().MTU), + MTU: topoProvider.Get().MTU(), GetMaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime), }, Msgr: msgr, @@ -224,16 +225,16 @@ func TestRegistrarRun(t *testing.T) { Convey("Faulty beacons are not sent", t, func() { mctrl := gomock.NewController(t) defer mctrl.Finish() - topoProvider := xtest.TopoProviderFromFile(t, topoNonCore) + topoProvider := itopotest.TopoProviderFromFile(t, topoNonCore) segProvider := mock_beaconing.NewMockSegmentProvider(mctrl) msgr := mock_infra.NewMockMessenger(mctrl) cfg := RegistrarConf{ Config: ExtenderConf{ - Signer: testSigner(t, priv, topoProvider.Get().ISD_AS), + Signer: testSigner(t, priv, topoProvider.Get().IA()), Mac: mac, - Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap, + Intfs: ifstate.NewInterfaces(topoProvider.Get().IFInfoMap(), ifstate.Config{}), - MTU: uint16(topoProvider.Get().MTU), + MTU: topoProvider.Get().MTU(), GetMaxExpTime: maxExpTimeFactory(beacon.DefaultMaxExpTime), }, Msgr: msgr, diff --git a/go/beacon_srv/internal/ifstate/BUILD.bazel b/go/beacon_srv/internal/ifstate/BUILD.bazel index 8bc74a92af..d908453edc 100644 --- a/go/beacon_srv/internal/ifstate/BUILD.bazel +++ b/go/beacon_srv/internal/ifstate/BUILD.bazel @@ -19,6 +19,7 @@ go_library( "//go/lib/ctrl/path_mgmt:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/messenger:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/log:go_default_library", "//go/lib/periodic:go_default_library", "//go/lib/serrors:go_default_library", @@ -47,6 +48,8 @@ go_test( "//go/lib/ctrl/path_mgmt:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/mock_infra:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", + "//go/lib/infra/modules/itopo/itopotest:go_default_library", "//go/lib/infra/modules/trust:go_default_library", "//go/lib/log:go_default_library", "//go/lib/scrypto:go_default_library", diff --git a/go/beacon_srv/internal/ifstate/handler_test.go b/go/beacon_srv/internal/ifstate/handler_test.go index f799b94e04..3a714577d9 100644 --- a/go/beacon_srv/internal/ifstate/handler_test.go +++ b/go/beacon_srv/internal/ifstate/handler_test.go @@ -26,12 +26,13 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/path_mgmt" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/mock_infra" - "github.com/scionproto/scion/go/lib/topology" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/xtest" ) func TestHandler(t *testing.T) { - topoProvider := xtest.TopoProviderFromFile(t, "testdata/topology.json") + topoProvider := itopotest.TopoProviderFromFile(t, "testdata/topology.json") type testDef struct { name string @@ -110,10 +111,10 @@ func TestHandler(t *testing.T) { } } -func interfaces(t *testing.T, topoProvider topology.Provider, +func interfaces(t *testing.T, topoProvider itopo.ProviderI, expectedIfSate *path_mgmt.IFStateInfos) *Interfaces { - intfs := NewInterfaces(topoProvider.Get().IFInfoMap, Config{}) + intfs := NewInterfaces(topoProvider.Get().IFInfoMap(), Config{}) activateAll(intfs) for _, info := range expectedIfSate.Infos { if !info.Active { diff --git a/go/beacon_srv/internal/ifstate/pusher.go b/go/beacon_srv/internal/ifstate/pusher.go index 0124a092ac..ce56ca3394 100644 --- a/go/beacon_srv/internal/ifstate/pusher.go +++ b/go/beacon_srv/internal/ifstate/pusher.go @@ -21,12 +21,12 @@ import ( "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/ctrl/path_mgmt" "github.com/scionproto/scion/go/lib/infra" - "github.com/scionproto/scion/go/lib/topology" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" ) // PusherConf is the configuration to create a new pusher. type PusherConf struct { - TopoProvider topology.Provider + TopoProvider itopo.ProviderI Intfs *Interfaces Msgr infra.Messenger } @@ -34,7 +34,7 @@ type PusherConf struct { // Pusher pushes interface state infos to all border routers to remove the // revocations. It is called when an interface comes back up. type Pusher struct { - topoProvider topology.Provider + topoProvider itopo.ProviderI intfs *Interfaces pusher brPusher } diff --git a/go/beacon_srv/internal/ifstate/pusher_test.go b/go/beacon_srv/internal/ifstate/pusher_test.go index d02450ae79..d5078cebbf 100644 --- a/go/beacon_srv/internal/ifstate/pusher_test.go +++ b/go/beacon_srv/internal/ifstate/pusher_test.go @@ -23,8 +23,7 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/path_mgmt" "github.com/scionproto/scion/go/lib/infra/mock_infra" - "github.com/scionproto/scion/go/lib/snet" - "github.com/scionproto/scion/go/lib/xtest" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" ) // TestPusherPush tests that if an interface is active the interface state info @@ -32,9 +31,9 @@ import ( func TestPusherPush(t *testing.T) { mctrl := gomock.NewController(t) defer mctrl.Finish() - topoProvider := xtest.TopoProviderFromFile(t, "testdata/topology.json") + topoProvider := itopotest.TopoProviderFromFile(t, "testdata/topology.json") msgr := mock_infra.NewMockMessenger(mctrl) - intfs := NewInterfaces(topoProvider.Get().IFInfoMap, Config{}) + intfs := NewInterfaces(topoProvider.Get().IFInfoMap(), Config{}) p := PusherConf{ TopoProvider: topoProvider, Intfs: intfs, @@ -57,12 +56,8 @@ func TestPusherPush(t *testing.T) { t.Run(fmt.Sprintf("Interface state: %s", state), func(t *testing.T) { intfs.Get(101).state = state if expectMsg { - for _, br := range topoProvider.Get().BR { - a := &snet.Addr{ - IA: topoProvider.Get().ISD_AS, - Host: br.CtrlAddrs.PublicAddr(br.CtrlAddrs.Overlay), - NextHop: br.CtrlAddrs.OverlayAddr(br.CtrlAddrs.Overlay), - } + for _, br := range topoProvider.Get().BRNames() { + a := topoProvider.Get().SBRAddress(br) msgr.EXPECT().SendIfStateInfos(gomock.Any(), gomock.Eq(expectedMsg), gomock.Eq(a), gomock.Any()) } diff --git a/go/beacon_srv/internal/ifstate/revoker.go b/go/beacon_srv/internal/ifstate/revoker.go index cc9eada256..c25fb6651a 100644 --- a/go/beacon_srv/internal/ifstate/revoker.go +++ b/go/beacon_srv/internal/ifstate/revoker.go @@ -26,10 +26,10 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/path_mgmt" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/messenger" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/periodic" "github.com/scionproto/scion/go/lib/snet" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/lib/util" ) @@ -49,7 +49,7 @@ type RevokerConf struct { Intfs *Interfaces Msgr infra.Messenger Signer infra.Signer - TopoProvider topology.Provider + TopoProvider itopo.ProviderI RevInserter RevInserter RevConfig RevConfig } @@ -141,8 +141,8 @@ func (r *Revoker) createSignedRev(ifid common.IFIDType) (*path_mgmt.SignedRevInf now := util.TimeToSecs(time.Now()) revInfo := &path_mgmt.RevInfo{ IfID: ifid, - RawIsdas: r.cfg.TopoProvider.Get().ISD_AS.IAInt(), - LinkType: r.cfg.TopoProvider.Get().IFInfoMap[ifid].LinkType, + RawIsdas: r.cfg.TopoProvider.Get().IA().IAInt(), + LinkType: r.cfg.TopoProvider.Get().IFInfoMap()[ifid].LinkType, RawTimestamp: now, RawTTL: uint32(r.cfg.RevConfig.RevTTL.Seconds()), } @@ -169,7 +169,7 @@ func (r *Revoker) pushRevocationsToPS(ctx context.Context, topo := r.cfg.TopoProvider.Get() labels := metrics.SentLabels{Dst: metrics.DstPS} - a := &snet.Addr{IA: topo.ISD_AS, Host: addr.NewSVCUDPAppAddr(addr.SvcPS)} + a := &snet.Addr{IA: topo.IA(), Host: addr.NewSVCUDPAppAddr(addr.SvcPS)} for ifid, srev := range revs { if err := r.cfg.Msgr.SendRev(ctx, srev, a, messenger.NextId()); err != nil { log.FromCtx(ctx).Error("[ifstate.Revoker] Failed to send revocation to PS", @@ -185,15 +185,10 @@ type brPusher struct { } func (p *brPusher) sendIfStateToAllBRs(ctx context.Context, msg *path_mgmt.IFStateInfos, - topo *topology.Topo, wg *sync.WaitGroup) { + topo itopo.Topology, wg *sync.WaitGroup) { - for id, br := range topo.BR { - a := &snet.Addr{ - IA: topo.ISD_AS, - Host: br.CtrlAddrs.PublicAddr(br.CtrlAddrs.Overlay), - NextHop: br.CtrlAddrs.OverlayAddr(br.CtrlAddrs.Overlay), - } - p.sendIfStateToBr(ctx, msg, id, a, wg) + for _, br := range topo.BRNames() { + p.sendIfStateToBr(ctx, msg, br, topo.SBRAddress(br), wg) } } diff --git a/go/beacon_srv/internal/ifstate/revoker_test.go b/go/beacon_srv/internal/ifstate/revoker_test.go index 5997d7dbb6..a2dcf28f5c 100644 --- a/go/beacon_srv/internal/ifstate/revoker_test.go +++ b/go/beacon_srv/internal/ifstate/revoker_test.go @@ -33,11 +33,12 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/path_mgmt" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/mock_infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/infra/modules/trust" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/scrypto" "github.com/scionproto/scion/go/lib/snet" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/lib/util" "github.com/scionproto/scion/go/lib/xtest" "github.com/scionproto/scion/go/lib/xtest/matchers" @@ -65,7 +66,7 @@ func TestMain(m *testing.M) { // TestNoRevocationIssued tests that if all interfaces receive if keepalives the revoker should do // nothing. func TestNoRevocationIssued(t *testing.T) { - topoProvider := xtest.TopoProviderFromFile(t, "testdata/topology.json") + topoProvider := itopotest.TopoProviderFromFile(t, "testdata/topology.json") _, priv, err := scrypto.GenKeyPair(scrypto.Ed25519) xtest.FailOnErr(t, err) signer := createTestSigner(t, priv) @@ -74,7 +75,7 @@ func TestNoRevocationIssued(t *testing.T) { defer mctrl.Finish() msgr := mock_infra.NewMockMessenger(mctrl) revInserter := mock_ifstate.NewMockRevInserter(mctrl) - intfs := NewInterfaces(topoProvider.Get().IFInfoMap, Config{}) + intfs := NewInterfaces(topoProvider.Get().IFInfoMap(), Config{}) activateAll(intfs) cfg := RevokerConf{ Intfs: intfs, @@ -96,7 +97,7 @@ func TestNoRevocationIssued(t *testing.T) { // TestRevokeInterface tests that if a keepalive didn't arrive for an interface it should be // revoked. func TestRevokeInterface(t *testing.T) { - topoProvider := xtest.TopoProviderFromFile(t, "testdata/topology.json") + topoProvider := itopotest.TopoProviderFromFile(t, "testdata/topology.json") pub, priv, err := scrypto.GenKeyPair(scrypto.Ed25519) xtest.FailOnErr(t, err) signer := createTestSigner(t, priv) @@ -105,7 +106,7 @@ func TestRevokeInterface(t *testing.T) { defer mctrl.Finish() msgr := mock_infra.NewMockMessenger(mctrl) revInserter := mock_ifstate.NewMockRevInserter(mctrl) - intfs := NewInterfaces(topoProvider.Get().IFInfoMap, Config{}) + intfs := NewInterfaces(topoProvider.Get().IFInfoMap(), Config{}) activateAll(intfs) intfs.Get(101).lastActivate = time.Now().Add(-expireTime) revInserter.EXPECT().InsertRevocations(gomock.Any(), &matchers.SignedRevs{ @@ -138,7 +139,7 @@ func TestRevokeInterface(t *testing.T) { // TestRevokedInterfaceNotRevokedImmediately tests that if an interface was revoked recently it // shouldn't be revoked again. func TestRevokedInterfaceNotRevokedImmediately(t *testing.T) { - topoProvider := xtest.TopoProviderFromFile(t, "testdata/topology.json") + topoProvider := itopotest.TopoProviderFromFile(t, "testdata/topology.json") _, priv, err := scrypto.GenKeyPair(scrypto.Ed25519) xtest.FailOnErr(t, err) signer := createTestSigner(t, priv) @@ -147,7 +148,7 @@ func TestRevokedInterfaceNotRevokedImmediately(t *testing.T) { defer mctrl.Finish() msgr := mock_infra.NewMockMessenger(mctrl) revInserter := mock_ifstate.NewMockRevInserter(mctrl) - intfs := NewInterfaces(topoProvider.Get().IFInfoMap, Config{}) + intfs := NewInterfaces(topoProvider.Get().IFInfoMap(), Config{}) activateAll(intfs) intfs.Get(101).state = Expired srev, err := path_mgmt.NewSignedRevInfo(&path_mgmt.RevInfo{ @@ -183,7 +184,7 @@ func TestRevokedInterfaceNotRevokedImmediately(t *testing.T) { // TestRevokedInterfaceRevokedAgain test that if an interface was revoked and the overlap period // started it should be revoked again. func TestRevokedInterfaceRevokedAgain(t *testing.T) { - topoProvider := xtest.TopoProviderFromFile(t, "testdata/topology.json") + topoProvider := itopotest.TopoProviderFromFile(t, "testdata/topology.json") pub, priv, err := scrypto.GenKeyPair(scrypto.Ed25519) xtest.FailOnErr(t, err) signer := createTestSigner(t, priv) @@ -192,7 +193,7 @@ func TestRevokedInterfaceRevokedAgain(t *testing.T) { defer mctrl.Finish() msgr := mock_infra.NewMockMessenger(mctrl) revInserter := mock_ifstate.NewMockRevInserter(mctrl) - intfs := NewInterfaces(topoProvider.Get().IFInfoMap, Config{}) + intfs := NewInterfaces(topoProvider.Get().IFInfoMap(), Config{}) activateAll(intfs) intfs.Get(101).state = Expired srev, err := path_mgmt.NewSignedRevInfo(&path_mgmt.RevInfo{ @@ -236,12 +237,12 @@ func TestRevokedInterfaceRevokedAgain(t *testing.T) { // TODO(lukedirtwalker): test revoking multiple interfaces at once. func expectMessengerCalls(msger *mock_infra.MockMessenger, - revokedIfId common.IFIDType, topoProvider topology.Provider) func(*testing.T, revVerifier) { + revokedIfId common.IFIDType, topoProvider itopo.ProviderI) func(*testing.T, revVerifier) { var brMsgs []brMsg var brMsgsMtx sync.Mutex - msger.EXPECT().SendIfStateInfos(gomock.Any(), - gomock.Any(), gomock.Any(), gomock.Any()).Times(len(topoProvider.Get().BR)).DoAndReturn( + msger.EXPECT().SendIfStateInfos(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Times(len(topoProvider.Get().BRNames())).DoAndReturn( func(_ context.Context, msg *path_mgmt.IFStateInfos, a net.Addr, _ uint64) error { brMsgsMtx.Lock() defer brMsgsMtx.Unlock() @@ -260,7 +261,7 @@ func expectMessengerCalls(msger *mock_infra.MockMessenger, return func(t *testing.T, verifier revVerifier) { Convey("Check sent BR messages", func() { SoMsg("Should send correct amount of messages", len(brMsgs), - ShouldEqual, len(topoProvider.Get().BR)) + ShouldEqual, len(topoProvider.Get().BRNames())) sentBRs := expectedBRs(topoProvider) for _, brMsg := range brMsgs { brName := brId(t, topoProvider, brMsg.a.(*snet.Addr)) @@ -280,7 +281,7 @@ func expectMessengerCalls(msger *mock_infra.MockMessenger, } func checkBRMessage(t *testing.T, brId string, infos *path_mgmt.IFStateInfos, - revokedIfId common.IFIDType, verifier revVerifier, topoProvider topology.Provider) { + revokedIfId common.IFIDType, verifier revVerifier, topoProvider itopo.ProviderI) { Convey(fmt.Sprintf("Check ifstateinfo for %s", brId), func() { SoMsg("Should contain correct amount of infos", len(infos.Infos), ShouldEqual, 1) @@ -291,7 +292,7 @@ func checkBRMessage(t *testing.T, brId string, infos *path_mgmt.IFStateInfos, } func checkRevocation(t *testing.T, srev *path_mgmt.SignedRevInfo, - revokedIfId common.IFIDType, verifier revVerifier, topoProvider topology.Provider) { + revokedIfId common.IFIDType, verifier revVerifier, topoProvider itopo.ProviderI) { Convey("Check revocation", func() { revInfo, err := srev.VerifiedRevInfo(context.Background(), verifier) @@ -299,7 +300,7 @@ func checkRevocation(t *testing.T, srev *path_mgmt.SignedRevInfo, SoMsg("correct ifId", revInfo.IfID, ShouldEqual, revokedIfId) SoMsg("correct IA", revInfo.RawIsdas, ShouldEqual, ia.IAInt()) SoMsg("correct linkType", revInfo.LinkType, - ShouldEqual, topoProvider.Get().IFInfoMap[revokedIfId].LinkType) + ShouldEqual, topoProvider.Get().IFInfoMap()[revokedIfId].LinkType) rawNow := util.TimeToSecs(time.Now()) SoMsg("recent revocation", revInfo.RawTimestamp, ShouldBeBetweenOrEqual, rawNow-1, rawNow) @@ -319,11 +320,11 @@ func checkInterfaces(intfs *Interfaces, nonActive map[common.IFIDType]State) { }) } -func brId(t *testing.T, topoProvider topology.Provider, saddr *snet.Addr) string { +func brId(t *testing.T, topoProvider itopo.ProviderI, saddr *snet.Addr) string { topo := topoProvider.Get() - for brId, brInfo := range topo.BR { - if brInfo.CtrlAddrs.PublicAddr(topo.Overlay).Equal(saddr.Host) { - return brId + for _, brID := range topo.BRNames() { + if topo.SBRAddress(brID).Host.Equal(saddr.Host) { + return brID } } t.Fatalf("Didn't find br ID for %s", saddr.Host) @@ -331,9 +332,9 @@ func brId(t *testing.T, topoProvider topology.Provider, saddr *snet.Addr) string } // expectedBRs return a set of BR ids for which we expect a if state update push. -func expectedBRs(topoProvider topology.Provider) map[string]struct{} { +func expectedBRs(topoProvider itopo.ProviderI) map[string]struct{} { brIds := make(map[string]struct{}) - for brId := range topoProvider.Get().BR { + for _, brId := range topoProvider.Get().BRNames() { brIds[brId] = struct{}{} } return brIds diff --git a/go/beacon_srv/internal/keepalive/BUILD.bazel b/go/beacon_srv/internal/keepalive/BUILD.bazel index 9bd59b213b..5c83cc5ec6 100644 --- a/go/beacon_srv/internal/keepalive/BUILD.bazel +++ b/go/beacon_srv/internal/keepalive/BUILD.bazel @@ -18,10 +18,10 @@ go_library( "//go/lib/ctrl:go_default_library", "//go/lib/ctrl/ifid:go_default_library", "//go/lib/infra:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/log:go_default_library", "//go/lib/periodic:go_default_library", "//go/lib/snet:go_default_library", - "//go/lib/topology:go_default_library", ], ) @@ -42,6 +42,7 @@ go_test( "//go/lib/ctrl:go_default_library", "//go/lib/ctrl/ifid:go_default_library", "//go/lib/infra:go_default_library", + "//go/lib/infra/modules/itopo/itopotest:go_default_library", "//go/lib/infra/modules/trust:go_default_library", "//go/lib/log:go_default_library", "//go/lib/scrypto:go_default_library", diff --git a/go/beacon_srv/internal/keepalive/sender.go b/go/beacon_srv/internal/keepalive/sender.go index 128bb898f6..a4ae22cc26 100644 --- a/go/beacon_srv/internal/keepalive/sender.go +++ b/go/beacon_srv/internal/keepalive/sender.go @@ -25,10 +25,10 @@ import ( "github.com/scionproto/scion/go/lib/ctrl" "github.com/scionproto/scion/go/lib/ctrl/ifid" "github.com/scionproto/scion/go/lib/infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/periodic" "github.com/scionproto/scion/go/lib/snet" - "github.com/scionproto/scion/go/lib/topology" ) var _ periodic.Task = (*Sender)(nil) @@ -37,7 +37,7 @@ var _ periodic.Task = (*Sender)(nil) type Sender struct { *onehop.Sender Signer infra.Signer - TopoProvider topology.Provider + TopoProvider itopo.ProviderI } // Name returns the tasks name. @@ -54,7 +54,7 @@ func (s *Sender) Run(ctx context.Context) { return } var sentIfids []common.IFIDType - for ifid, intf := range topo.IFInfoMap { + for ifid, intf := range topo.IFInfoMap() { l := metrics.KeepaliveLabels{IfID: ifid, Result: metrics.ErrProcess} pld, err := s.createPld(ifid) if err != nil { diff --git a/go/beacon_srv/internal/keepalive/sender_test.go b/go/beacon_srv/internal/keepalive/sender_test.go index 59c9036f4c..16c737b1ae 100644 --- a/go/beacon_srv/internal/keepalive/sender_test.go +++ b/go/beacon_srv/internal/keepalive/sender_test.go @@ -27,6 +27,7 @@ import ( "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/ctrl" "github.com/scionproto/scion/go/lib/infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/infra/modules/trust" "github.com/scionproto/scion/go/lib/scrypto" "github.com/scionproto/scion/go/lib/snet" @@ -38,7 +39,7 @@ func TestSenderRun(t *testing.T) { t.Log("Run sends ifid packets on all interfaces") mctrl := gomock.NewController(t) defer mctrl.Finish() - topoProvider := xtest.TopoProviderFromFile(t, "testdata/topology.json") + topoProvider := itopotest.TopoProviderFromFile(t, "testdata/topology.json") mac, err := scrypto.InitMac(make(common.RawBytes, 16)) require.NoError(t, err) pub, priv, err := scrypto.GenKeyPair(scrypto.Ed25519) @@ -57,7 +58,7 @@ func TestSenderRun(t *testing.T) { Signer: createTestSigner(t, priv), TopoProvider: topoProvider, } - pkts := make([]*snet.SCIONPacket, 0, len(topoProvider.Get().IFInfoMap)) + pkts := make([]*snet.SCIONPacket, 0, len(topoProvider.Get().IFInfoMap())) conn.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Times(cap(pkts)).DoAndReturn( func(ipkts, _ interface{}) error { pkts = append(pkts, ipkts.(*snet.SCIONPacket)) @@ -72,7 +73,7 @@ func TestSenderRun(t *testing.T) { assert.NoError(t, err, "SPldErr") pld, err := spld.GetVerifiedPld(nil, testVerifier(pub)) assert.NoError(t, err, "PldErr") - _, ok := topoProvider.Get().IFInfoMap[pld.IfID.OrigIfID] + _, ok := topoProvider.Get().IFInfoMap()[pld.IfID.OrigIfID] assert.True(t, ok) } } diff --git a/go/beacon_srv/main.go b/go/beacon_srv/main.go index 7f5524d590..1c8d200696 100644 --- a/go/beacon_srv/main.go +++ b/go/beacon_srv/main.go @@ -113,14 +113,13 @@ func realMain() int { ServiceType: proto.ServiceType_bs, TopoProvider: itopo.Provider(), } - trustStore := trust.NewStore(trustDB, topo.ISD_AS, trustConf, log.Root()) + trustStore := trust.NewStore(trustDB, topo.IA(), trustConf, log.Root()) err = trustStore.LoadAuthoritativeCrypto(filepath.Join(cfg.General.ConfigDir, "certs")) if err != nil { log.Crit("Unable to load local crypto", "err", err) return 1 } - topoAddress := topo.BS.GetById(cfg.General.ID) - if topoAddress == nil { + if !topo.Exists(addr.SvcBS, cfg.General.ID) { log.Crit("Unable to find topo address") return 1 } @@ -132,9 +131,9 @@ func realMain() int { defer trCloser.Close() opentracing.SetGlobalTracer(tracer) nc := infraenv.NetworkConfig{ - IA: topo.ISD_AS, - Public: env.GetPublicSnetAddress(topo.ISD_AS, topoAddress), - Bind: env.GetBindSnetAddress(topo.ISD_AS, topoAddress), + IA: topo.IA(), + Public: topo.SPublicAddress(addr.SvcBS, cfg.General.ID), + Bind: topo.SBindAddress(addr.SvcBS, cfg.General.ID), SVC: addr.SvcBS, ReconnectToDispatcher: cfg.General.ReconnectToDispatcher, QUIC: infraenv.QUIC{ @@ -152,22 +151,22 @@ func realMain() int { return 1 } defer msgr.CloseServer() - store, err := loadStore(topo.Core, topo.ISD_AS, cfg) + store, err := loadStore(topo.Core(), topo.IA(), cfg) if err != nil { log.Crit("Unable to open beacon store", "err", err) return 1 } defer store.Close() - intfs = ifstate.NewInterfaces(topo.IFInfoMap, ifstate.Config{}) + intfs = ifstate.NewInterfaces(topo.IFInfoMap(), ifstate.Config{}) prometheus.MustRegister(ifstate.NewCollector(intfs)) msgr.AddHandler(infra.ChainRequest, trustStore.NewChainReqHandler(false)) msgr.AddHandler(infra.TRCRequest, trustStore.NewTRCReqHandler(false)) msgr.AddHandler(infra.IfStateReq, ifstate.NewHandler(intfs)) msgr.AddHandler(infra.SignedRev, revocation.NewHandler(store, trustStore.NewVerifier(), 5*time.Second)) - msgr.AddHandler(infra.Seg, beaconing.NewHandler(topo.ISD_AS, intfs, store, + msgr.AddHandler(infra.Seg, beaconing.NewHandler(topo.IA(), intfs, store, trustStore.NewVerifier())) - msgr.AddHandler(infra.IfId, keepalive.NewHandler(topo.ISD_AS, intfs, + msgr.AddHandler(infra.IfId, keepalive.NewHandler(topo.IA(), intfs, keepalive.StateChangeTasks{ RevDropper: store, IfStatePusher: ifstate.PusherConf{ @@ -183,7 +182,6 @@ func realMain() int { defer log.LogPanicAndExit() msgr.ListenAndServe() }() - ovAddr := &addr.AppAddr{L3: topoAddress.PublicAddr(topoAddress.Overlay).L3} dispatcherService := reliable.NewDispatcherService("") if cfg.General.ReconnectToDispatcher { dispatcherService = reconnect.NewDispatcherService(dispatcherService) @@ -193,7 +191,9 @@ func realMain() int { } // We do not need to drain the connection, since the src address is spoofed // to contain the topo address. - conn, _, err := pktDisp.RegisterTimeout(topo.ISD_AS, ovAddr, nil, addr.SvcNone, time.Second) + ovAddr := topo.PublicAddress(addr.SvcBS, cfg.General.ID) + ovAddr.L4 = addr.NewL4UDPInfo(0) + conn, _, err := pktDisp.RegisterTimeout(topo.IA(), ovAddr, nil, addr.SvcNone, time.Second) if err != nil { log.Crit("Unable to create SCION packet conn", "err", err) return 1 @@ -213,7 +213,7 @@ func realMain() int { }, ), } - signer, err := tasks.createSigner(topo) + signer, err := tasks.createSigner(topo.IA()) if err != nil { log.Crit(infraenv.ErrAppUnableToInitMessenger, "err", err) return 1 @@ -265,7 +265,7 @@ type periodicTasks struct { trustDB trustdb.TrustDB store beaconstorage.Store msgr infra.Messenger - topoProvider topology.Provider + topoProvider itopo.ProviderI allowIsdLoop bool addressRewriter *messenger.AddressRewriter @@ -291,7 +291,7 @@ func (t *periodicTasks) Start() error { } t.running = true topo := t.topoProvider.Get() - topoAddress := topo.BS.GetById(cfg.General.ID) + topoAddress := topo.PublicAddress(addr.SvcBS, cfg.General.ID) if topoAddress == nil { return serrors.New("Unable to find topo address") } @@ -323,7 +323,7 @@ func (t *periodicTasks) Start() error { func (t *periodicTasks) startRevoker() (*periodic.Runner, error) { topo := t.topoProvider.Get() - signer, err := t.createSigner(topo) + signer, err := t.createSigner(topo.IA()) if err != nil { return nil, err } @@ -342,13 +342,13 @@ func (t *periodicTasks) startRevoker() (*periodic.Runner, error) { cfg.BS.ExpiredCheckInterval.Duration), nil } -func (t *periodicTasks) startKeepaliveSender(a *topology.TopoAddr) (*periodic.Runner, error) { +func (t *periodicTasks) startKeepaliveSender(a *addr.AppAddr) (*periodic.Runner, error) { s := &keepalive.Sender{ Sender: &onehop.Sender{ Conn: t.conn, - IA: t.topoProvider.Get().ISD_AS, + IA: t.topoProvider.Get().IA(), MAC: t.genMac(), - Addr: a.PublicAddr(a.Overlay), + Addr: a, }, Signer: infra.NullSigner, TopoProvider: t.topoProvider, @@ -357,12 +357,12 @@ func (t *periodicTasks) startKeepaliveSender(a *topology.TopoAddr) (*periodic.Ru cfg.BS.KeepaliveInterval.Duration), nil } -func (t *periodicTasks) startOriginator(a *topology.TopoAddr) (*periodic.Runner, error) { +func (t *periodicTasks) startOriginator(a *addr.AppAddr) (*periodic.Runner, error) { topo := t.topoProvider.Get() - if !topo.Core { + if !topo.Core() { return nil, nil } - signer, err := t.createSigner(topo) + signer, err := t.createSigner(topo.IA()) if err != nil { return nil, err } @@ -370,9 +370,9 @@ func (t *periodicTasks) startOriginator(a *topology.TopoAddr) (*periodic.Runner, BeaconSender: &onehop.BeaconSender{ Sender: onehop.Sender{ Conn: t.conn, - IA: topo.ISD_AS, + IA: topo.IA(), MAC: t.genMac(), - Addr: a.PublicAddr(a.Overlay), + Addr: a, }, AddressRewriter: t.addressRewriter, QUICBeaconSender: t.msgr, @@ -380,7 +380,7 @@ func (t *periodicTasks) startOriginator(a *topology.TopoAddr) (*periodic.Runner, Config: beaconing.ExtenderConf{ Intfs: t.intfs, Mac: t.genMac(), - MTU: uint16(topo.MTU), + MTU: topo.MTU(), Signer: signer, GetMaxExpTime: maxExpTimeFactory(t.store, beacon.PropPolicy), }, @@ -393,22 +393,22 @@ func (t *periodicTasks) startOriginator(a *topology.TopoAddr) (*periodic.Runner, cfg.BS.OriginationInterval.Duration), nil } -func (t *periodicTasks) startPropagator(a *topology.TopoAddr) (*periodic.Runner, error) { +func (t *periodicTasks) startPropagator(a *addr.AppAddr) (*periodic.Runner, error) { topo := t.topoProvider.Get() - signer, err := t.createSigner(topo) + signer, err := t.createSigner(topo.IA()) if err != nil { return nil, err } p, err := beaconing.PropagatorConf{ BeaconProvider: t.store, AllowIsdLoop: t.allowIsdLoop, - Core: topo.Core, + Core: topo.Core(), BeaconSender: &onehop.BeaconSender{ Sender: onehop.Sender{ Conn: t.conn, - IA: topo.ISD_AS, + IA: topo.IA(), MAC: t.genMac(), - Addr: a.PublicAddr(a.Overlay), + Addr: a, }, AddressRewriter: t.addressRewriter, QUICBeaconSender: t.msgr, @@ -416,7 +416,7 @@ func (t *periodicTasks) startPropagator(a *topology.TopoAddr) (*periodic.Runner, Config: beaconing.ExtenderConf{ Intfs: t.intfs, Mac: t.genMac(), - MTU: uint16(topo.MTU), + MTU: topo.MTU(), Signer: signer, GetMaxExpTime: maxExpTimeFactory(t.store, beacon.PropPolicy), }, @@ -431,7 +431,7 @@ func (t *periodicTasks) startPropagator(a *topology.TopoAddr) (*periodic.Runner, func (t *periodicTasks) startSegRegRunners() (segRegRunners, error) { topo := t.topoProvider.Get() - s := segRegRunners{core: topo.Core} + s := segRegRunners{core: topo.Core()} var err error if s.core { s.coreRegistrar, err = t.startRegistrar(topo, proto.PathSegType_core, beacon.CoreRegPolicy) @@ -451,10 +451,10 @@ func (t *periodicTasks) startSegRegRunners() (segRegRunners, error) { return s, nil } -func (t *periodicTasks) startRegistrar(topo *topology.Topo, segType proto.PathSegType, +func (t *periodicTasks) startRegistrar(topo itopo.Topology, segType proto.PathSegType, policyType beacon.PolicyType) (*periodic.Runner, error) { - signer, err := t.createSigner(topo) + signer, err := t.createSigner(topo.IA()) if err != nil { return nil, err } @@ -467,33 +467,33 @@ func (t *periodicTasks) startRegistrar(topo *topology.Topo, segType proto.PathSe Config: beaconing.ExtenderConf{ Intfs: t.intfs, Mac: t.genMac(), - MTU: uint16(topo.MTU), + MTU: topo.MTU(), Signer: signer, GetMaxExpTime: maxExpTimeFactory(t.store, policyType), }, }.New() if err != nil { - return nil, common.NewBasicError("Unable to start registrar", err, "type", segType) + return nil, common.NewBasicError("unable to start registrar", err, "type", segType) } return periodic.Start(r, 500*time.Millisecond, cfg.BS.RegistrationInterval.Duration), nil } -func (t *periodicTasks) createSigner(topo *topology.Topo) (infra.Signer, error) { +func (t *periodicTasks) createSigner(ia addr.IA) (infra.Signer, error) { dir := filepath.Join(cfg.General.ConfigDir, "keys") cfg, err := keyconf.Load(dir, false, false, false, false) if err != nil { - return nil, common.NewBasicError("Unable to load key config", err) + return nil, common.NewBasicError("unable to load key config", err) } ctx, cancelF := context.WithTimeout(context.Background(), time.Second) defer cancelF() - meta, err := trust.CreateSignMeta(ctx, topo.ISD_AS, t.trustDB) + meta, err := trust.CreateSignMeta(ctx, ia, t.trustDB) if err != nil { - return nil, common.NewBasicError("Unable to create sign meta", err) + return nil, common.NewBasicError("unable to create sign meta", err) } signer, err := trust.NewBasicSigner(cfg.SignKey, meta) if err != nil { - return nil, common.NewBasicError("Unable to create signer", err) + return nil, common.NewBasicError("unable to create signer", err) } return signer, nil } @@ -566,7 +566,7 @@ func handleTopoUpdate() { if intfs == nil { return } - intfs.Update(itopo.Get().IFInfoMap) + intfs.Update(itopo.Get().IFInfoMap()) } func loadStore(core bool, ia addr.IA, cfg config.Config) (beaconstorage.Store, error) { diff --git a/go/border/BUILD.bazel b/go/border/BUILD.bazel index 1fef910b37..451d59f1b9 100644 --- a/go/border/BUILD.bazel +++ b/go/border/BUILD.bazel @@ -66,12 +66,12 @@ go_test( "//go/border/rpkt:go_default_library", "//go/lib/addr:go_default_library", "//go/lib/common:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/log:go_default_library", "//go/lib/overlay:go_default_library", "//go/lib/overlay/conn:go_default_library", "//go/lib/overlay/conn/mock_conn:go_default_library", "//go/lib/ringbuf:go_default_library", - "//go/lib/topology:go_default_library", "//go/lib/xtest:go_default_library", "@com_github_golang_mock//gomock:go_default_library", "@com_github_smartystreets_goconvey//convey:go_default_library", diff --git a/go/border/brconf/BUILD.bazel b/go/border/brconf/BUILD.bazel index 382632859f..b5fee775de 100644 --- a/go/border/brconf/BUILD.bazel +++ b/go/border/brconf/BUILD.bazel @@ -16,6 +16,7 @@ go_library( "//go/lib/config:go_default_library", "//go/lib/env:go_default_library", "//go/lib/infra/modules/idiscovery:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/keyconf:go_default_library", "//go/lib/topology:go_default_library", ], diff --git a/go/border/brconf/conf.go b/go/border/brconf/conf.go index fd5f054498..904a43e304 100644 --- a/go/border/brconf/conf.go +++ b/go/border/brconf/conf.go @@ -22,6 +22,7 @@ import ( "github.com/scionproto/scion/go/lib/addr" "github.com/scionproto/scion/go/lib/common" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/keyconf" "github.com/scionproto/scion/go/lib/topology" ) @@ -31,7 +32,7 @@ import ( type BRConf struct { // Topo contains the names of all local infrastructure elements, a map // of interface IDs to routers, and the actual topology. - Topo *topology.Topo + Topo itopo.Topology // IA is the current ISD-AS. IA addr.IA // BR is the topology information of this router. @@ -58,7 +59,7 @@ func Load(id, confDir string) (*BRConf, error) { // WithNewTopo creates config that shares all content except fields related // to topology with the oldConf. -func WithNewTopo(id string, topo *topology.Topo, oldConf *BRConf) (*BRConf, error) { +func WithNewTopo(id string, topo itopo.Topology, oldConf *BRConf) (*BRConf, error) { conf := &BRConf{ Dir: oldConf.Dir, MasterKeys: oldConf.MasterKeys, @@ -73,7 +74,7 @@ func WithNewTopo(id string, topo *topology.Topo, oldConf *BRConf) (*BRConf, erro // entries related to topo in the config. func (cfg *BRConf) loadTopo(id string) error { topoPath := filepath.Join(cfg.Dir, topology.CfgName) - topo, err := topology.LoadFromFile(topoPath) + topo, err := itopo.LoadFromFile(topoPath) if err != nil { return err } @@ -84,11 +85,11 @@ func (cfg *BRConf) loadTopo(id string) error { } // initTopo initializesthe entries related to topo in the config. -func (cfg *BRConf) initTopo(id string, topo *topology.Topo) error { +func (cfg *BRConf) initTopo(id string, topo itopo.Topology) error { cfg.Topo = topo - cfg.IA = cfg.Topo.ISD_AS + cfg.IA = cfg.Topo.IA() // Find the config for this router. - topoBR, ok := cfg.Topo.BR[id] + topoBR, ok := cfg.Topo.BR(id) if !ok { return common.NewBasicError("Unable to find element ID in topology", nil, "id", id) diff --git a/go/border/ifstate/ifstate.go b/go/border/ifstate/ifstate.go index 140ed2f952..9d22b800f2 100644 --- a/go/border/ifstate/ifstate.go +++ b/go/border/ifstate/ifstate.go @@ -109,7 +109,7 @@ func Process(ifStates *path_mgmt.IFStateInfos) { return } } - intf, ok := ctx.Conf.Topo.IFInfoMap[ifid] + intf, ok := ctx.Conf.Topo.IFInfoMap()[ifid] if !ok { log.Warn("Interface ID does not exist", "ifid", ifid) continue diff --git a/go/border/rctx/BUILD.bazel b/go/border/rctx/BUILD.bazel index 0f412b4a19..6744c1b9b4 100644 --- a/go/border/rctx/BUILD.bazel +++ b/go/border/rctx/BUILD.bazel @@ -19,8 +19,6 @@ go_library( "//go/lib/overlay:go_default_library", "//go/lib/overlay/conn:go_default_library", "//go/lib/ringbuf:go_default_library", - "//go/lib/scmp:go_default_library", "//go/lib/scrypto:go_default_library", - "//go/lib/topology:go_default_library", ], ) diff --git a/go/border/rctx/rctx.go b/go/border/rctx/rctx.go index fb4d1aecab..c545bf8779 100644 --- a/go/border/rctx/rctx.go +++ b/go/border/rctx/rctx.go @@ -18,7 +18,6 @@ package rctx import ( - "math/rand" "sync" "sync/atomic" @@ -26,9 +25,7 @@ import ( "github.com/scionproto/scion/go/lib/addr" "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/overlay" - "github.com/scionproto/scion/go/lib/scmp" "github.com/scionproto/scion/go/lib/scrypto" - "github.com/scionproto/scion/go/lib/topology" ) // Ctx is the main router context structure. @@ -91,69 +88,13 @@ func (ctx *Ctx) ResolveSVC(svc addr.HostSVC) ([]*overlay.OverlayAddr, error) { // ResolveSVCAny resolves an anycast SVC address (i.e. a single instance of a local // infrastructure service). func (ctx *Ctx) ResolveSVCAny(svc addr.HostSVC) (*overlay.OverlayAddr, error) { - names, elemMap, err := ctx.GetSVCNamesMap(svc) - if err != nil { - return nil, err - } - // XXX(kormat): just pick one randomly. TCP will remove the need to have - // consistent selection for a given source. - name := names[rand.Intn(len(names))] - elem := elemMap[name] - return elem.OverlayAddr(ctx.Conf.Topo.Overlay), nil + return ctx.Conf.Topo.OverlayAnycast(svc) } // ResolveSVCMulti resolves a multicast SVC address (i.e. one packet per machine hosting // instances for a local infrastructure service). func (ctx *Ctx) ResolveSVCMulti(svc addr.HostSVC) ([]*overlay.OverlayAddr, error) { - _, elemMap, err := ctx.GetSVCNamesMap(svc) - if err != nil { - return nil, err - } - // Only send once per IP:OverlayPort combination. Adding the overlay port - // allows this to work even when multiple instances are NAT'd to the same - // IP address. - uniqAddrs := make(map[string]struct{}) - overAddrs := []*overlay.OverlayAddr{} - ot := ctx.Conf.Topo.Overlay - for _, elem := range elemMap { - overAddr := elem.OverlayAddr(ot) - addrStr := overAddr.String() - if _, ok := uniqAddrs[addrStr]; ok { - continue - } - uniqAddrs[addrStr] = struct{}{} - overAddrs = append(overAddrs, overAddr) - } - return overAddrs, nil -} - -// GetSVCNamesMap returns the slice of instance names and addresses for a given SVC address. -func (ctx *Ctx) GetSVCNamesMap(svc addr.HostSVC) ([]string, - map[string]topology.TopoAddr, error) { - - t := ctx.Conf.Topo - var names []string - var elemMap map[string]topology.TopoAddr - switch svc.Base() { - case addr.SvcBS: - names, elemMap = t.BSNames, t.BS - case addr.SvcPS: - names, elemMap = t.PSNames, t.PS - case addr.SvcCS: - names, elemMap = t.CSNames, t.CS - case addr.SvcSB: - names, elemMap = t.SBNames, t.SB - case addr.SvcSIG: - names, elemMap = t.SIGNames, t.SIG - default: - return nil, nil, common.NewBasicError("Unsupported SVC address", - scmp.NewError(scmp.C_Routing, scmp.T_R_BadHost, nil, nil), "svc", svc) - } - if len(elemMap) == 0 { - return nil, nil, common.NewBasicError("No instances found for SVC address", - scmp.NewError(scmp.C_Routing, scmp.T_R_UnreachHost, nil, nil), "svc", svc) - } - return names, elemMap, nil + return ctx.Conf.Topo.OverlayMulticast(svc) } // Get returns a pointer to the current router context. diff --git a/go/border/rpkt/create.go b/go/border/rpkt/create.go index 5e18d3dae3..7b4c7d8dce 100644 --- a/go/border/rpkt/create.go +++ b/go/border/rpkt/create.go @@ -179,7 +179,7 @@ func (rp *RtrPkt) CreateReplyScnPkt() (*spkt.ScnPkt, error) { } sp.SrcIA = rp.Ctx.Conf.IA // Use the local address as the source host - pub := rp.Ctx.Conf.BR.InternalAddrs.PublicOverlay(rp.Ctx.Conf.Topo.Overlay) + pub := rp.Ctx.Conf.BR.InternalAddrs.PublicOverlay(rp.Ctx.Conf.Topo.Overlay()) sp.SrcHost = pub.L3() return sp, nil } diff --git a/go/border/rpkt/path.go b/go/border/rpkt/path.go index 80cb653634..7ced9db9f4 100644 --- a/go/border/rpkt/path.go +++ b/go/border/rpkt/path.go @@ -85,7 +85,7 @@ func (rp *RtrPkt) validateLocalIF(ifid *common.IFIDType) error { if ifid == nil { return serrors.New("validateLocalIF: Interface is nil") } - if _, ok := rp.Ctx.Conf.Topo.IFInfoMap[*ifid]; !ok { + if _, ok := rp.Ctx.Conf.Topo.IFInfoMap()[*ifid]; !ok { // No such interface. return common.NewBasicError( "Unknown IF", diff --git a/go/border/rpkt/process.go b/go/border/rpkt/process.go index de8b7bf15d..65a7c7d18e 100644 --- a/go/border/rpkt/process.go +++ b/go/border/rpkt/process.go @@ -188,14 +188,14 @@ func (rp *RtrPkt) processSCMPRevocation() error { intf := rp.Ctx.Conf.BR.IFs[*rp.ifCurr] rp.SrcIA() // Ensure that rp.srcIA has been set - if (rp.dstIA.I == rp.Ctx.Conf.Topo.ISD_AS.I && intf.LinkType == proto.LinkType_core) || - (rp.srcIA.I == rp.Ctx.Conf.Topo.ISD_AS.I && intf.LinkType == proto.LinkType_parent) { + if (rp.dstIA.I == rp.Ctx.Conf.Topo.IA().I && intf.LinkType == proto.LinkType_core) || + (rp.srcIA.I == rp.Ctx.Conf.Topo.IA().I && intf.LinkType == proto.LinkType_parent) { // Case 1 & 2 args.Addrs = append(args.Addrs, addr.SvcBS) - if len(rp.Ctx.Conf.Topo.PS) > 0 { + if len(rp.Ctx.Conf.Topo.SVCNames(addr.SvcPS)) > 0 { args.Addrs = append(args.Addrs, addr.SvcPS) } - } else if rp.dstIA.Equal(rp.Ctx.Conf.IA) && len(rp.Ctx.Conf.Topo.PS) > 0 { + } else if rp.dstIA.Equal(rp.Ctx.Conf.IA) && len(rp.Ctx.Conf.Topo.SVCNames(addr.SvcPS)) > 0 { // Case 3 args.Addrs = append(args.Addrs, addr.SvcPS) } diff --git a/go/border/rpkt/route.go b/go/border/rpkt/route.go index 73b384332a..5c4a4cfa2a 100644 --- a/go/border/rpkt/route.go +++ b/go/border/rpkt/route.go @@ -138,8 +138,8 @@ func (rp *RtrPkt) forwardFromExternal() (HookResult, error) { rp.RefInc(1) return rp.reprocess() } - nextBR := rp.Ctx.Conf.Topo.IFInfoMap[*rp.ifNext] - dst := nextBR.InternalAddrs.PublicOverlay(rp.Ctx.Conf.Topo.Overlay) + nextBR := rp.Ctx.Conf.Topo.IFInfoMap()[*rp.ifNext] + dst := nextBR.InternalAddrs.PublicOverlay(rp.Ctx.Conf.Topo.Overlay()) rp.Egress = append(rp.Egress, EgressPair{S: rp.Ctx.LocSockOut, Dst: dst}) return HookContinue, nil } @@ -194,7 +194,7 @@ func (rp *RtrPkt) xoverFromExternal() error { return nil } prevLink := rp.Ctx.Conf.BR.IFs[origIFCurr].LinkType - nextLink := rp.Ctx.Conf.Topo.IFInfoMap[*rp.ifNext].LinkType + nextLink := rp.Ctx.Conf.Topo.IFInfoMap()[*rp.ifNext].LinkType // Never allowed to switch between core segments. if prevLink == proto.LinkType_core && nextLink == proto.LinkType_core { return common.NewBasicError("Segment change between CORE links", diff --git a/go/border/rpkt/validate.go b/go/border/rpkt/validate.go index 1496c3fbab..c35bcbd8f0 100644 --- a/go/border/rpkt/validate.go +++ b/go/border/rpkt/validate.go @@ -42,7 +42,7 @@ func (rp *RtrPkt) Validate() (bool, error) { } mtu = intf.MTU } else { - mtu = rp.Ctx.Conf.Topo.MTU + mtu = int(rp.Ctx.Conf.Topo.MTU()) } // XXX(kormat): the rest of the common header is checked by the parsing phase. if !addr.HostTypeCheck(rp.CmnHdr.DstType) { diff --git a/go/border/setup-posix.go b/go/border/setup-posix.go index 27f26318b0..6fc05e584d 100644 --- a/go/border/setup-posix.go +++ b/go/border/setup-posix.go @@ -82,7 +82,7 @@ func (p posixLoc) Rollback(r *Router, ctx *rctx.Ctx, oldCtx *rctx.Ctx) error { func (p posixLoc) addSock(r *Router, ctx *rctx.Ctx) error { // Get Bind address if set, Public otherwise - bind := ctx.Conf.BR.InternalAddrs.BindOrPublicOverlay(ctx.Conf.Topo.Overlay) + bind := ctx.Conf.BR.InternalAddrs.BindOrPublicOverlay(ctx.Conf.Topo.Overlay()) log.Debug("Setting up new local socket.", "bind", bind) // Listen on the socket. over, err := conn.New(bind, nil, nil) @@ -112,7 +112,7 @@ func (p posixExt) Setup(r *Router, ctx *rctx.Ctx, intf *topology.IFInfo, oldCtx // Reuse socket if the interface has not changed. if !interfaceChanged(intf, oldIntf) { log.Trace("No change detected for external socket.", "conn", - intf.Local.BindOrPublicOverlay(ctx.Conf.Topo.Overlay)) + intf.Local.BindOrPublicOverlay(ctx.Conf.Topo.Overlay())) ctx.ExtSockIn[intf.Id] = oldCtx.ExtSockIn[intf.Id] ctx.ExtSockOut[intf.Id] = oldCtx.ExtSockOut[intf.Id] return nil diff --git a/go/border/setup.go b/go/border/setup.go index 1ffbbd0b56..1eac5cfbe9 100644 --- a/go/border/setup.go +++ b/go/border/setup.go @@ -77,7 +77,7 @@ func (r *Router) setup() error { } // Initialize itopo. itopo.Init(r.Id, proto.ServiceType_br, itopo.Callbacks{CleanDynamic: r.setupCtxOnClean}) - if _, _, err := itopo.SetStatic(conf.Topo, true); err != nil { + if _, _, err := itopo.SetStatic(conf.Topo.Raw(), true); err != nil { return err } // Setup new context. @@ -127,14 +127,14 @@ func (r *Router) setupCtxFromConfig(config *brconf.BRConf) error { // We want to keep in sync itopo and the context that is set. // We attempt to set the context with the topology that will be current // after setting itopo. If setting itopo fails in the end, we rollback the context. - tx, err := itopo.BeginSetStatic(config.Topo, true) + tx, err := itopo.BeginSetStatic(config.Topo.Raw(), true) if err != nil { return err } // Set config to use the appropriate topology. The returned topology is // not necessarily the same as config.Topo. It can be another static // or dynamic topology. - newConf, err := brconf.WithNewTopo(r.Id, tx.Get(), config) + newConf, err := brconf.WithNewTopo(r.Id, itopo.NewTopologyFromRaw(tx.Get()), config) if err != nil { return err } @@ -170,7 +170,7 @@ func (r *Router) setupCtxFromTopoUpdate(mode discovery.Mode, tx itopo.Transactio return false, nil } log.Trace("====> Setting up new context from topology update", "mode", mode) - newConf, err := brconf.WithNewTopo(r.Id, tx.Get(), rctx.Get().Conf) + newConf, err := brconf.WithNewTopo(r.Id, itopo.NewTopologyFromRaw(tx.Get()), rctx.Get().Conf) if err != nil { return false, err } diff --git a/go/border/setup_test.go b/go/border/setup_test.go index 71b5621886..720b6172e6 100644 --- a/go/border/setup_test.go +++ b/go/border/setup_test.go @@ -25,10 +25,10 @@ import ( "github.com/scionproto/scion/go/border/rctx" "github.com/scionproto/scion/go/border/rpkt" "github.com/scionproto/scion/go/lib/common" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/overlay" "github.com/scionproto/scion/go/lib/ringbuf" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/lib/xtest" ) @@ -360,22 +360,15 @@ func closeAllSocks(ctx *rctx.Ctx) { } func loadConfig(t *testing.T) *brconf.BRConf { - topo := loadTopo(t) - topo, err := topology.LoadFromFile("testdata/topology.json") + topo, err := itopo.LoadFromFile("testdata/topology.json") xtest.FailOnErr(t, err) - topoBr, ok := topo.BR["br1-ff00_0_111-1"] + topoBR, ok := topo.BR("br1-ff00_0_111-1") if !ok { t.Fatal("BR ID not found") } return &brconf.BRConf{ Topo: topo, - IA: topo.ISD_AS, - BR: &topoBr, + IA: topo.IA(), + BR: &topoBR, } } - -func loadTopo(t *testing.T) *topology.Topo { - topo, err := topology.LoadFromFile("testdata/topology.json") - xtest.FailOnErr(t, err) - return topo -} diff --git a/go/cert_srv/BUILD.bazel b/go/cert_srv/BUILD.bazel index 92a9d32e9c..1648d0c04c 100644 --- a/go/cert_srv/BUILD.bazel +++ b/go/cert_srv/BUILD.bazel @@ -29,7 +29,6 @@ go_library( "//go/lib/prom:go_default_library", "//go/lib/serrors:go_default_library", "//go/lib/snet:go_default_library", - "//go/lib/topology:go_default_library", "//go/proto:go_default_library", "@com_github_burntsushi_toml//:go_default_library", "@com_github_opentracing_opentracing_go//:go_default_library", diff --git a/go/cert_srv/main.go b/go/cert_srv/main.go index 2d1eb0f9ba..182472e129 100644 --- a/go/cert_srv/main.go +++ b/go/cert_srv/main.go @@ -110,7 +110,7 @@ func startReissRunner() { if !cfg.CS.DisableCorePush { corePusher = periodic.Start( &reiss.CorePusher{ - LocalIA: itopo.Get().ISD_AS, + LocalIA: itopo.Get().IA(), TrustDB: state.TrustDB, Msger: msgr, }, @@ -123,13 +123,13 @@ func startReissRunner() { log.Info("Reissue disabled, not starting reiss task.") return } - if itopo.Get().Core { + if itopo.Get().Core() { log.Info("Starting periodic reiss.Self task") reissRunner = periodic.Start( &reiss.Self{ Msgr: msgr, State: state, - IA: itopo.Get().ISD_AS, + IA: itopo.Get().IA(), IssTime: cfg.CS.IssuerReissueLeadTime.Duration, LeafTime: cfg.CS.LeafReissueLeadTime.Duration, CorePusher: corePusher, @@ -145,7 +145,7 @@ func startReissRunner() { &reiss.Requester{ Msgr: msgr, State: state, - IA: itopo.Get().ISD_AS, + IA: itopo.Get().IA(), LeafTime: cfg.CS.LeafReissueLeadTime.Duration, CorePusher: corePusher, }, diff --git a/go/cert_srv/setup.go b/go/cert_srv/setup.go index 3e1ffb811a..85b8e13667 100644 --- a/go/cert_srv/setup.go +++ b/go/cert_srv/setup.go @@ -36,7 +36,6 @@ import ( "github.com/scionproto/scion/go/lib/prom" "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/snet" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/proto" ) @@ -68,11 +67,11 @@ func setup() error { return common.NewBasicError("Unable to validate config", err) } itopo.Init(cfg.General.ID, proto.ServiceType_cs, itopo.Callbacks{}) - topo, err := topology.LoadFromFile(cfg.General.Topology) + topo, err := itopo.LoadFromFile(cfg.General.Topology) if err != nil { return common.NewBasicError("Unable to load topology", err) } - if _, _, err := itopo.SetStatic(topo, false); err != nil { + if _, _, err := itopo.SetStatic(topo.Raw(), false); err != nil { return common.NewBasicError("Unable to set initial static topology", err) } // Set environment to listen for signals. @@ -81,7 +80,7 @@ func setup() error { log.Error("Unable to reload", "err", err) } }) - router, err := infraenv.NewRouter(topo.ISD_AS, cfg.Sciond) + router, err := infraenv.NewRouter(topo.IA(), cfg.Sciond) if err != nil { return common.NewBasicError("Unable to initialize path router", err) } @@ -129,16 +128,16 @@ func initState(cfg *config.Config, router snet.Router) error { Router: router, TopoProvider: itopo.Provider(), } - trustStore := trust.NewStore(trustDB, topo.ISD_AS, trustConf, log.Root()) + trustStore := trust.NewStore(trustDB, topo.IA(), trustConf, log.Root()) err = trustStore.LoadAuthoritativeCrypto(filepath.Join(cfg.General.ConfigDir, "certs")) if err != nil { return common.NewBasicError("Unable to load local crypto", err) } - state, err = config.LoadState(cfg.General.ConfigDir, topo.Core, trustDB, trustStore) + state, err = config.LoadState(cfg.General.ConfigDir, topo.Core(), trustDB, trustStore) if err != nil { return common.NewBasicError("Unable to load CS state", err) } - if err = setDefaultSignerVerifier(state, topo.ISD_AS); err != nil { + if err = setDefaultSignerVerifier(state, topo.IA()); err != nil { return common.NewBasicError("Unable to set default signer and verifier", err) } return nil @@ -166,14 +165,13 @@ func setDefaultSignerVerifier(c *config.State, pubIA addr.IA) error { // cfg.CS. This function may only be called once per config. func setMessenger(cfg *config.Config, router snet.Router) error { topo := itopo.Get() - topoAddress := topo.CS.GetById(cfg.General.ID) - if topoAddress == nil { - return serrors.New("Unable to find topo address") + if !topo.Exists(addr.SvcCS, cfg.General.ID) { + return serrors.New("unable to find topo address") } nc := infraenv.NetworkConfig{ - IA: topo.ISD_AS, - Public: env.GetPublicSnetAddress(topo.ISD_AS, topoAddress), - Bind: env.GetBindSnetAddress(topo.ISD_AS, topoAddress), + IA: topo.IA(), + Public: topo.SPublicAddress(addr.SvcCS, cfg.General.ID), + Bind: topo.SBindAddress(addr.SvcCS, cfg.General.ID), SVC: addr.SvcCS, ReconnectToDispatcher: cfg.General.ReconnectToDispatcher, QUIC: infraenv.QUIC{ @@ -198,10 +196,10 @@ func setMessenger(cfg *config.Config, router snet.Router) error { msgr.UpdateSigner(state.GetSigner(), []infra.MessageType{infra.ChainIssueRequest}) msgr.UpdateVerifier(state.GetVerifier()) // Only core CS handles certificate reissuance requests. - if topo.Core { + if topo.Core() { msgr.AddHandler(infra.ChainIssueRequest, &reiss.Handler{ State: state, - IA: topo.ISD_AS, + IA: topo.IA(), }) } return nil diff --git a/go/lib/env/BUILD.bazel b/go/lib/env/BUILD.bazel index 00ca7a3e26..a07ad9ba42 100644 --- a/go/lib/env/BUILD.bazel +++ b/go/lib/env/BUILD.bazel @@ -12,17 +12,14 @@ go_library( importpath = "github.com/scionproto/scion/go/lib/env", visibility = ["//visibility:public"], deps = [ - "//go/lib/addr:go_default_library", "//go/lib/common:go_default_library", "//go/lib/config:go_default_library", "//go/lib/fatal:go_default_library", "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/log:go_default_library", - "//go/lib/overlay:go_default_library", "//go/lib/sciond:go_default_library", "//go/lib/scrypto:go_default_library", "//go/lib/serrors:go_default_library", - "//go/lib/snet:go_default_library", "//go/lib/topology:go_default_library", "//go/lib/util:go_default_library", "@com_github_opentracing_opentracing_go//:go_default_library", diff --git a/go/lib/env/env.go b/go/lib/env/env.go index 9a8575d74e..9989ef070b 100644 --- a/go/lib/env/env.go +++ b/go/lib/env/env.go @@ -34,17 +34,14 @@ import ( "github.com/uber/jaeger-client-go" jaegercfg "github.com/uber/jaeger-client-go/config" - "github.com/scionproto/scion/go/lib/addr" "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/config" "github.com/scionproto/scion/go/lib/fatal" "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/log" - "github.com/scionproto/scion/go/lib/overlay" "github.com/scionproto/scion/go/lib/sciond" _ "github.com/scionproto/scion/go/lib/scrypto" // Make sure math/rand is seeded "github.com/scionproto/scion/go/lib/serrors" - "github.com/scionproto/scion/go/lib/snet" "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/lib/util" ) @@ -205,30 +202,6 @@ func ReloadTopology(topologyPath string) { log.Info("Reloaded topology") } -func GetPublicSnetAddress(ia addr.IA, topoAddr *topology.TopoAddr) *snet.Addr { - // snet only supports udp4 for now - if topoAddr.Overlay != overlay.UDPIPv4 { - panic("unsupported overlay") - } - pub := topoAddr.PublicAddr(topoAddr.Overlay) - if pub == nil { - return nil - } - return &snet.Addr{IA: ia, Host: pub} -} - -func GetBindSnetAddress(ia addr.IA, topoAddr *topology.TopoAddr) *snet.Addr { - // snet only supports udp4 for now - if topoAddr.Overlay != overlay.UDPIPv4 { - panic("unsupported overlay") - } - bind := topoAddr.BindAddr(topoAddr.Overlay) - if bind == nil { - return nil - } - return &snet.Addr{IA: ia, Host: bind} -} - var _ config.Config = (*Metrics)(nil) type Metrics struct { diff --git a/go/lib/infra/messenger/BUILD.bazel b/go/lib/infra/messenger/BUILD.bazel index 1c725c26bd..733f07d5d2 100644 --- a/go/lib/infra/messenger/BUILD.bazel +++ b/go/lib/infra/messenger/BUILD.bazel @@ -28,6 +28,7 @@ go_library( "//go/lib/infra:go_default_library", "//go/lib/infra/disp:go_default_library", "//go/lib/infra/messenger/internal/metrics:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/infra/rpc:go_default_library", "//go/lib/log:go_default_library", "//go/lib/overlay:go_default_library", @@ -36,7 +37,6 @@ go_library( "//go/lib/serrors:go_default_library", "//go/lib/snet:go_default_library", "//go/lib/svc:go_default_library", - "//go/lib/topology:go_default_library", "//go/lib/tracing:go_default_library", "//go/lib/util:go_default_library", "//go/proto:go_default_library", diff --git a/go/lib/infra/messenger/addr.go b/go/lib/infra/messenger/addr.go index 6ed09e6486..396961e87e 100644 --- a/go/lib/infra/messenger/addr.go +++ b/go/lib/infra/messenger/addr.go @@ -22,13 +22,12 @@ import ( "github.com/scionproto/scion/go/lib/addr" "github.com/scionproto/scion/go/lib/common" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/overlay" "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/snet" "github.com/scionproto/scion/go/lib/svc" - "github.com/scionproto/scion/go/lib/topology" - "github.com/scionproto/scion/go/proto" ) // Resolver performs SVC resolution for a remote AS, thus converting an anycast @@ -269,34 +268,16 @@ type LocalSVCRouter interface { // NewSVCRouter build a SVC router backed by topology information from the // specified provider. -func NewSVCRouter(tp topology.Provider) LocalSVCRouter { +func NewSVCRouter(tp itopo.ProviderI) LocalSVCRouter { return &baseSVCRouter{ topology: tp, } } type baseSVCRouter struct { - topology topology.Provider + topology itopo.ProviderI } func (r *baseSVCRouter) GetOverlay(svc addr.HostSVC) (*overlay.OverlayAddr, error) { - topo := r.topology.Get() - topoAddr, err := topo.GetAnyTopoAddr(toProtoServiceType(svc)) - if err != nil { - return nil, common.NewBasicError("Failed to look up SVC in topology", err, "svc", svc) - } - return topoAddr.OverlayAddr(topo.Overlay), nil -} - -func toProtoServiceType(svc addr.HostSVC) proto.ServiceType { - switch svc { - case addr.SvcCS: - return proto.ServiceType_cs - case addr.SvcPS: - return proto.ServiceType_ps - case addr.SvcBS: - return proto.ServiceType_bs - default: - panic("bad service address") - } + return r.topology.Get().OverlayAnycast(svc) } diff --git a/go/lib/infra/modules/idiscovery/idiscovery.go b/go/lib/infra/modules/idiscovery/idiscovery.go index 28fea6fea7..6850aab4b4 100644 --- a/go/lib/infra/modules/idiscovery/idiscovery.go +++ b/go/lib/infra/modules/idiscovery/idiscovery.go @@ -308,7 +308,7 @@ func NewFetcher(handler TopoHandler, params discovery.FetchParams, } var err error t.fetcher, err = topofetcher.New( - itopo.Get().DS, + itopo.Get().DS(), params, topofetcher.Callbacks{ Error: t.handleErr, @@ -328,7 +328,7 @@ func (t *task) Name() string { } func (t *task) Run(ctx context.Context) { - if err := t.fetcher.UpdateInstances(itopo.Get().DS); err != nil { + if err := t.fetcher.UpdateInstances(itopo.Get().DS()); err != nil { t.logger(ctx).Error("[discovery] Unable to update instances", "err", err) return } diff --git a/go/lib/infra/modules/itopo/BUILD.bazel b/go/lib/infra/modules/itopo/BUILD.bazel index 86586f882a..2dd99fb1fe 100644 --- a/go/lib/infra/modules/itopo/BUILD.bazel +++ b/go/lib/infra/modules/itopo/BUILD.bazel @@ -6,16 +6,22 @@ go_library( "cleaner.go", "doc.go", "itopo.go", + "topology.go", "validate.go", ], importpath = "github.com/scionproto/scion/go/lib/infra/modules/itopo", visibility = ["//visibility:public"], deps = [ + "//go/lib/addr:go_default_library", "//go/lib/common:go_default_library", + "//go/lib/hostinfo:go_default_library", "//go/lib/infra/modules/itopo/internal/metrics:go_default_library", "//go/lib/log:go_default_library", + "//go/lib/overlay:go_default_library", "//go/lib/periodic:go_default_library", + "//go/lib/scmp:go_default_library", "//go/lib/serrors:go_default_library", + "//go/lib/snet:go_default_library", "//go/lib/topology:go_default_library", "//go/proto:go_default_library", "@com_github_google_go_cmp//cmp:go_default_library", diff --git a/go/lib/infra/modules/itopo/itopo.go b/go/lib/infra/modules/itopo/itopo.go index 919f21f656..2978fd5b6d 100644 --- a/go/lib/infra/modules/itopo/itopo.go +++ b/go/lib/infra/modules/itopo/itopo.go @@ -42,11 +42,15 @@ type Callbacks struct { UpdateStatic func() } +type ProviderI interface { + Get() Topology +} + // providerFunc wraps the Get call as a topology provider. -type providerFunc func() *topology.Topo +type providerFunc func() Topology // Provider returns a topology provider that calls Get internally. -func Provider() topology.Provider { +func Provider() ProviderI { st.RLock() defer st.RUnlock() if st.topo.static == nil { @@ -55,7 +59,7 @@ func Provider() topology.Provider { return providerFunc(Get) } -func (f providerFunc) Get() *topology.Topo { +func (f providerFunc) Get() Topology { return f() } @@ -69,10 +73,12 @@ func Init(id string, svc proto.ServiceType, clbks Callbacks) { } // Get atomically gets the pointer to the current topology. -func Get() *topology.Topo { +func Get() Topology { st.RLock() defer st.RUnlock() - return st.topo.Get() + return &topologyS{ + Topology: st.topo.Get(), + } } // SetDynamic atomically sets the dynamic topology. The returned topology is a pointer diff --git a/go/lib/infra/modules/itopo/itopotest/BUILD.bazel b/go/lib/infra/modules/itopo/itopotest/BUILD.bazel new file mode 100644 index 0000000000..a63c19350c --- /dev/null +++ b/go/lib/infra/modules/itopo/itopotest/BUILD.bazel @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["itopotest.go"], + importpath = "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest", + visibility = ["//visibility:public"], + deps = [ + "//go/lib/infra/modules/itopo:go_default_library", + "//go/lib/topology:go_default_library", + "@com_github_stretchr_testify//require:go_default_library", + ], +) diff --git a/go/lib/xtest/topo.go b/go/lib/infra/modules/itopo/itopotest/itopotest.go similarity index 80% rename from go/lib/xtest/topo.go rename to go/lib/infra/modules/itopo/itopotest/itopotest.go index cc9da8d09b..193257f5d8 100644 --- a/go/lib/xtest/topo.go +++ b/go/lib/infra/modules/itopo/itopotest/itopotest.go @@ -1,4 +1,4 @@ -// Copyright 2019 Anapaya Systems +// Copyright 2019 ETH Zurich // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,11 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package xtest +package itopotest import ( "testing" + "github.com/stretchr/testify/require" + + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/topology" ) @@ -30,11 +33,11 @@ type TestTopoProvider struct { func TopoProviderFromFile(t *testing.T, fName string) *TestTopoProvider { t.Helper() topo, err := topology.LoadFromFile(fName) - FailOnErr(t, err) + require.NoError(t, err) return &TestTopoProvider{Topo: topo} } // Get returns the stored topology. -func (t *TestTopoProvider) Get() *topology.Topo { - return t.Topo +func (t *TestTopoProvider) Get() itopo.Topology { + return itopo.NewTopologyFromRaw(t.Topo) } diff --git a/go/lib/infra/modules/itopo/topology.go b/go/lib/infra/modules/itopo/topology.go new file mode 100644 index 0000000000..b1ed0de95f --- /dev/null +++ b/go/lib/infra/modules/itopo/topology.go @@ -0,0 +1,426 @@ +// Copyright 2019 ETH Zurich +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package itopo + +import ( + "github.com/scionproto/scion/go/lib/addr" + "github.com/scionproto/scion/go/lib/common" + "github.com/scionproto/scion/go/lib/hostinfo" + "github.com/scionproto/scion/go/lib/overlay" + "github.com/scionproto/scion/go/lib/scmp" + "github.com/scionproto/scion/go/lib/serrors" + "github.com/scionproto/scion/go/lib/snet" + "github.com/scionproto/scion/go/lib/topology" + "github.com/scionproto/scion/go/proto" +) + +type Topology interface { + // IA returns the local ISD-AS number. + IA() addr.IA + // MTU returns the MTU of the local AS. + MTU() uint16 + // Core returns whether the local AS is core. + Core() bool + // InterfaceIDs returns all interface IDS from the local AS. + InterfaceIDs() []common.IFIDType + + // PublicAddress gets the public address of a server with the requested type and name, and nil + // if no such server exists. + // + // FIXME(scrye): See whether this or its snet variant below can be removed. + PublicAddress(svc addr.HostSVC, name string) *addr.AppAddr + // SPublicAddress gets the public address of a server with the requested type and name, and nil + // if no such server exists. + // + // FIXME(scrye): See whether this or its app variant above can be removed. + SPublicAddress(svc addr.HostSVC, name string) *snet.Addr + + // Exists returns true if the service and name are present in the topology file. + Exists(svc addr.HostSVC, name string) bool + + // BindAddress gets the bind address of a server with the requested type and name, and nil + // if no such server exists. + // + // FIXME(scrye): See whether this or its snet variant below can be removed. + BindAddress(svc addr.HostSVC, name string) *addr.AppAddr + // BindAddress gets the bind address of a server with the requested type and name, and nil + // if no such server exists. + // + // FIXME(scrye): See whether this or its app variant above can be removed. + SBindAddress(svc addr.HostSVC, name string) *snet.Addr + + // SBRAddress returns the internal public address of the BR with the specified name. + SBRAddress(name string) *snet.Addr + + // OverlayAnycast returns the overlay address for an arbitrary server of the requested type. + OverlayAnycast(svc addr.HostSVC) (*overlay.OverlayAddr, error) + // OverlayMulticast returns all overlay addresses for the requested type. + OverlayMulticast(svc addr.HostSVC) ([]*overlay.OverlayAddr, error) + // OverlayByName returns the overlay address of the server name of the requested type. + // + // FIXME(scrye): This isn't really needed. We should also get rid of it. + OverlayByName(svc addr.HostSVC, name string) (*overlay.OverlayAddr, error) + // OverlayNextHop2 returns the internal overlay address of the router containing the ID. The + // return value is encoded as an overlay address. + // + // FIXME(scrye): Remove either this or the other method. A single return type should be + // supported. + OverlayNextHop2(ifID common.IFIDType) (*overlay.OverlayAddr, bool) + + // OverlayNextHop returns the internal overlay address of the router containing the interface + // ID. The return value is encoded as a SCIOND host info struct. + // + // XXX(scrye): Return value is a shallow copy. + OverlayNextHop(ifID common.IFIDType) (hostinfo.Host, bool) + + // MakeHostInfos returns the overlay addresses of all services for the specified service type. + // + // XXX(scrye): The return values are shallow copies. + MakeHostInfos(st proto.ServiceType) []hostinfo.Host + + // BR returns information for a specific border router + // + // FIXME(scrye): Simplify return type and make it topology format agnostic. + // + // XXX(scrye): Return value is a shallow copy. + BR(name string) (topology.BRInfo, bool) + // IFInfoMap returns the mapping between interface IDs an internal addresses. + // + // FIXME(scrye): Simplify return type and make it topology format agnostic. + // + // XXX(scrye): Return value is a shallow copy. + IFInfoMap() topology.IfInfoMap + + // BRNames returns the names of all BRs in the topology. + // + // FIXME(scrye): Remove this, callers shouldn't care about names. + // + // XXX(scrye): Return value is a shallow copy. + BRNames() []string + + // SVCNames returns the names of all servers in the topology for the specified service. + // + // FIXME(scrye): Remove this, callers shouldn't care about names. + // + // XXX(scrye): Return value is a shallow copy. + SVCNames(svc addr.HostSVC) []string + + // Raw returns a pointer to the underlying topology object. This is included for legacy + // reasons and should never be used. + // + // FIXME(scrye): Remove this. + // + // XXX(scrye): Return value is a shallow copy. + Raw() *topology.Topo + // Overlay returns the overlay running in the current AS. + // + // FIXME(scrye): Remove this. + Overlay() overlay.Type + + // DS returns the discovery servers in the topology. + // + // FIXME(scrye): Simplify return type and make it topology format agnostic. + // + // XXX(scrye): Return value is a shallow copy. + DS() topology.IDAddrMap +} + +// NewTopology creates a new empty topology. +func NewTopology() Topology { + return &topologyS{ + Topology: &topology.Topo{}, + } +} + +// NewTopologyFromRaw wraps the high level topology interface API around a raw topology object. +func NewTopologyFromRaw(topo *topology.Topo) Topology { + return &topologyS{ + Topology: topo, + } +} + +type ServiceType string + +func LoadFromFile(path string) (Topology, error) { + t, err := topology.LoadFromFile(path) + if err != nil { + return nil, err + } + return &topologyS{ + Topology: t, + }, nil +} + +type topologyS struct { + Topology *topology.Topo +} + +func (t *topologyS) DS() topology.IDAddrMap { + return t.Topology.DS +} + +func (t *topologyS) IA() addr.IA { + return t.Topology.ISD_AS +} + +func (t *topologyS) MTU() uint16 { + return uint16(t.Topology.MTU) +} + +func (t *topologyS) InterfaceIDs() []common.IFIDType { + intfs := make([]common.IFIDType, 0, len(t.Topology.IFInfoMap)) + for ifid := range t.Topology.IFInfoMap { + intfs = append(intfs, ifid) + } + return intfs +} + +func (t *topologyS) OverlayNextHop(ifid common.IFIDType) (hostinfo.Host, bool) { + ifInfo, ok := t.Topology.IFInfoMap[ifid] + if !ok { + return hostinfo.Host{}, false + } + return hostinfo.FromTopoBRAddr(*ifInfo.InternalAddrs), true +} + +func (t *topologyS) OverlayNextHop2(ifid common.IFIDType) (*overlay.OverlayAddr, bool) { + ifInfo, ok := t.Topology.IFInfoMap[ifid] + if !ok { + return nil, false + } + return ifInfo.InternalAddrs.PublicOverlay(t.Topology.Overlay).Copy(), true +} + +func (t *topologyS) MakeHostInfos(st proto.ServiceType) []hostinfo.Host { + var hostInfos []hostinfo.Host + addresses, err := t.Topology.GetAllTopoAddrs(st) + if err != nil { + // FIXME(lukedirtwalker): inform client about this: + // see https://github.com/scionproto/scion/issues/1673 + return hostInfos + } + for _, a := range addresses { + hostInfos = append(hostInfos, hostinfo.FromTopoAddr(a)) + } + return hostInfos +} + +func (t *topologyS) Core() bool { + return t.Topology.Core +} + +func (t *topologyS) BR(name string) (topology.BRInfo, bool) { + br, ok := t.Topology.BR[name] + return br, ok +} + +func (t *topologyS) SPublicAddress(svc addr.HostSVC, name string) *snet.Addr { + address := t.PublicAddress(svc, name) + if address == nil { + return nil + } + return &snet.Addr{ + IA: t.IA(), + Host: address.Copy(), + } +} + +func (t *topologyS) PublicAddress(svc addr.HostSVC, name string) *addr.AppAddr { + topoAddr := t.topoAddress(svc, name) + if topoAddr == nil { + return nil + } + publicAddr := topoAddr.PublicAddr(topoAddr.Overlay) + if publicAddr == nil { + return nil + } + return publicAddr.Copy() +} + +func (t *topologyS) Exists(svc addr.HostSVC, name string) bool { + return t.PublicAddress(svc, name) != nil +} + +func (t *topologyS) SBindAddress(svc addr.HostSVC, name string) *snet.Addr { + address := t.BindAddress(svc, name) + if address == nil { + return nil + } + return &snet.Addr{ + IA: t.IA(), + Host: address.Copy(), + } +} + +func (t *topologyS) BindAddress(svc addr.HostSVC, name string) *addr.AppAddr { + topoAddr := t.topoAddress(svc, name) + if topoAddr == nil { + return nil + } + bindAddr := topoAddr.BindAddr(topoAddr.Overlay) + if bindAddr == nil { + return nil + } + return bindAddr.Copy() +} + +func (t *topologyS) topoAddress(svc addr.HostSVC, name string) *topology.TopoAddr { + var addresses topology.IDAddrMap + switch svc.Base() { + case addr.SvcBS: + addresses = t.Topology.BS + case addr.SvcCS: + addresses = t.Topology.CS + case addr.SvcPS: + addresses = t.Topology.PS + case addr.SvcSIG: + addresses = t.Topology.SIG + } + if addresses == nil { + return nil + } + return addresses.GetById(name) +} + +func (t *topologyS) OverlayAnycast(svc addr.HostSVC) (*overlay.OverlayAddr, error) { + st, err := toProtoServiceType(svc) + if err != nil { + return nil, err + } + topoAddr, err := t.Topology.GetAnyTopoAddr(st) + if err != nil { + // FIXME(scrye): Return this error because some calling code in the BR searches for it. + // Ideally, the error should be communicated in a more explicit way. + return nil, common.NewBasicError("No instances found for SVC address", + scmp.NewError(scmp.C_Routing, scmp.T_R_UnreachHost, nil, nil), "svc", svc) + } + overlayAddr := topoAddr.OverlayAddr(t.Topology.Overlay) + if overlayAddr == nil { + return nil, serrors.New("overlay address not found", "svc", svc) + } + return overlayAddr.Copy(), nil +} + +func (t *topologyS) OverlayMulticast(svc addr.HostSVC) ([]*overlay.OverlayAddr, error) { + st, err := toProtoServiceType(svc) + if err != nil { + return nil, err + } + topoAddrs, err := t.Topology.GetAllTopoAddrs(st) + if err != nil { + return nil, serrors.WrapStr("SVC not supported", err, "svc", svc) + } + + if len(topoAddrs) == 0 { + // FIXME(scrye): Return this error because some calling code in the BR searches for it. + // Ideally, the error should be communicated in a more explicit way. + return nil, common.NewBasicError("No instances found for SVC address", + scmp.NewError(scmp.C_Routing, scmp.T_R_UnreachHost, nil, nil), "svc", svc) + } + + // Only select each IP:OverlayPort combination once, s.t. the same message isn't multicasted + // multiple times by the remote dispatcher. + uniqueOverlayAddrs := make(map[string]*overlay.OverlayAddr) + for _, topoAddr := range topoAddrs { + overlayAddr := topoAddr.OverlayAddr(t.Topology.Overlay) + if overlayAddr == nil { + continue + } + uniqueOverlayAddrs[overlayAddr.String()] = overlayAddr + } + + var overlayAddrs []*overlay.OverlayAddr + for _, overlayAddr := range uniqueOverlayAddrs { + overlayAddrs = append(overlayAddrs, overlayAddr.Copy()) + } + return overlayAddrs, nil +} + +func (t *topologyS) OverlayByName(svc addr.HostSVC, name string) (*overlay.OverlayAddr, error) { + st, err := toProtoServiceType(svc) + if err != nil { + return nil, err + } + topoAddr, err := t.Topology.GetTopoAddr(name, st) + if err != nil { + return nil, serrors.WrapStr("SVC not supported", err, "svc", svc) + } + overlayAddr := topoAddr.OverlayAddr(t.Topology.Overlay) + if overlayAddr == nil { + return nil, serrors.New("overlay address not found", "svc", svc) + } + return overlayAddr.Copy(), nil +} + +func toProtoServiceType(svc addr.HostSVC) (proto.ServiceType, error) { + switch svc.Base() { + case addr.SvcBS: + return proto.ServiceType_bs, nil + case addr.SvcCS: + return proto.ServiceType_cs, nil + case addr.SvcPS: + return proto.ServiceType_ps, nil + case addr.SvcSIG: + return proto.ServiceType_sig, nil + default: + // FIXME(scrye): Return this error because some calling code in the BR searches for it. + // Ideally, the error should be communicated in a more explicit way. + return 0, common.NewBasicError("Unsupported SVC address", + scmp.NewError(scmp.C_Routing, scmp.T_R_BadHost, nil, nil), "svc", svc) + } +} + +func (t *topologyS) IFInfoMap() topology.IfInfoMap { + return t.Topology.IFInfoMap +} + +func (t *topologyS) BRNames() []string { + return t.Topology.BRNames +} + +func (t *topologyS) SBRAddress(name string) *snet.Addr { + br, ok := t.Topology.BR[name] + if !ok { + return nil + } + return &snet.Addr{ + IA: t.IA(), + Host: br.CtrlAddrs.PublicAddr(br.CtrlAddrs.Overlay), + NextHop: br.CtrlAddrs.OverlayAddr(br.CtrlAddrs.Overlay), + } +} + +func (t *topologyS) SVCNames(svc addr.HostSVC) []string { + switch svc.Base() { + case addr.SvcBS: + return t.Topology.BSNames + case addr.SvcCS: + return t.Topology.CSNames + case addr.SvcPS: + return t.Topology.PSNames + case addr.SvcSIG: + return t.Topology.SIGNames + default: + return nil + } +} + +func (t *topologyS) Overlay() overlay.Type { + return t.Topology.Overlay +} + +func (t *topologyS) Raw() *topology.Topo { + return t.Topology +} diff --git a/go/lib/infra/modules/trust/BUILD.bazel b/go/lib/infra/modules/trust/BUILD.bazel index 51c768e664..bd842800f5 100644 --- a/go/lib/infra/modules/trust/BUILD.bazel +++ b/go/lib/infra/modules/trust/BUILD.bazel @@ -20,6 +20,7 @@ go_library( "//go/lib/infra:go_default_library", "//go/lib/infra/dedupe:go_default_library", "//go/lib/infra/messenger:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/infra/modules/trust/internal/metrics:go_default_library", "//go/lib/infra/modules/trust/trustdb:go_default_library", "//go/lib/log:go_default_library", @@ -28,7 +29,6 @@ go_library( "//go/lib/scrypto/trc:go_default_library", "//go/lib/serrors:go_default_library", "//go/lib/snet:go_default_library", - "//go/lib/topology:go_default_library", "//go/lib/util:go_default_library", "//go/proto:go_default_library", "@com_github_opentracing_opentracing_go//:go_default_library", @@ -55,6 +55,7 @@ go_test( "//go/lib/infra/disp:go_default_library", "//go/lib/infra/messenger:go_default_library", "//go/lib/infra/mock_infra:go_default_library", + "//go/lib/infra/modules/itopo/itopotest:go_default_library", "//go/lib/infra/modules/trust/trustdb/trustdbsqlite:go_default_library", "//go/lib/log:go_default_library", "//go/lib/scrypto:go_default_library", diff --git a/go/lib/infra/modules/trust/config.go b/go/lib/infra/modules/trust/config.go index 7e46322a93..9573344876 100644 --- a/go/lib/infra/modules/trust/config.go +++ b/go/lib/infra/modules/trust/config.go @@ -15,8 +15,8 @@ package trust import ( + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/snet" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/proto" ) @@ -34,5 +34,5 @@ type Config struct { // Router is used to determine paths to other ASes. Router snet.Router // TopoProvider provides the local topology. - TopoProvider topology.Provider + TopoProvider itopo.ProviderI } diff --git a/go/lib/infra/modules/trust/trust.go b/go/lib/infra/modules/trust/trust.go index 15de8c0dd4..0770937636 100644 --- a/go/lib/infra/modules/trust/trust.go +++ b/go/lib/infra/modules/trust/trust.go @@ -33,6 +33,7 @@ import ( "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/dedupe" "github.com/scionproto/scion/go/lib/infra/messenger" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/infra/modules/trust/internal/metrics" "github.com/scionproto/scion/go/lib/infra/modules/trust/trustdb" "github.com/scionproto/scion/go/lib/log" @@ -41,7 +42,6 @@ import ( "github.com/scionproto/scion/go/lib/scrypto/trc" "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/snet" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/proto" ) @@ -217,7 +217,7 @@ func (store *Store) getTRC(ctx context.Context, isd addr.ISD, version scrypto.Ve return trcObj, nil } if store.config.ServiceType == proto.ServiceType_cs && - store.config.TopoProvider.Get().Core && store.ia.I == isd { + store.config.TopoProvider.Get().Core() && store.ia.I == isd { // Core CS can't find TRC for its own ISD metrics.Store.Lookup(l.WithResult(metrics.ErrNotFoundAuth)).Inc() @@ -375,7 +375,7 @@ func (store *Store) getChain(ctx context.Context, ia addr.IA, version scrypto.Ve return chain, nil } isCS := store.config.ServiceType == proto.ServiceType_cs - isCore := store.config.TopoProvider.Get().Core + isCore := store.config.TopoProvider.Get().Core() if (isCS && store.ia.Equal(ia)) || (isCS && isCore && store.ia.I == ia.I) || (store.config.MustHaveLocalChain && store.ia.Equal(ia) && version.IsLatest()) { @@ -776,15 +776,15 @@ func (store *Store) ChooseServer(ctx context.Context, destination addr.IA) (net. // * a local core CS if destination is isd-local or any core CS. // * a remote core CS if destination is remote isd. func (store *Store) chooseDestCSIsd(ctx context.Context, destination addr.IA, - topo *topology.Topo) (addr.ISD, error) { + topo itopo.Topology) (addr.ISD, error) { // For isd-local dests use local core. - if destination.I == topo.ISD_AS.I { - return topo.ISD_AS.I, nil + if destination.I == topo.IA().I { + return topo.IA().I, nil } // For wildcards or any core dest use local core. if destination.A == 0 { - return topo.ISD_AS.I, nil + return topo.IA().I, nil } opts := infra.ASInspectorOpts{RequiredAttributes: []infra.Attribute{infra.Core}} core, err := store.HasAttributes(ctx, destination, opts) @@ -792,7 +792,7 @@ func (store *Store) chooseDestCSIsd(ctx context.Context, destination addr.IA, return 0, err } if core { - return topo.ISD_AS.I, nil + return topo.IA().I, nil } // For non-core dests in a remote isd use remote core. return destination.I, nil diff --git a/go/lib/infra/modules/trust/trust_test.go b/go/lib/infra/modules/trust/trust_test.go index 698e5f9e9a..790a17c299 100644 --- a/go/lib/infra/modules/trust/trust_test.go +++ b/go/lib/infra/modules/trust/trust_test.go @@ -33,6 +33,7 @@ import ( "github.com/scionproto/scion/go/lib/infra/disp" "github.com/scionproto/scion/go/lib/infra/messenger" "github.com/scionproto/scion/go/lib/infra/mock_infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo/itopotest" "github.com/scionproto/scion/go/lib/infra/modules/trust/trustdb/trustdbsqlite" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/scrypto" @@ -644,7 +645,7 @@ func initStore(t *testing.T, ctrl *gomock.Controller, topotestutil.AddServer(topo, proto.ServiceType_cs, "foo", topology.TestTopoAddr(nil, nil, nil, nil)) cfg := Config{ - TopoProvider: &xtest.TestTopoProvider{ + TopoProvider: &itopotest.TestTopoProvider{ Topo: topo, }, } diff --git a/go/lib/snet/addrutil/BUILD.bazel b/go/lib/snet/addrutil/BUILD.bazel index 1b45fc1a6a..19b448d7b0 100644 --- a/go/lib/snet/addrutil/BUILD.bazel +++ b/go/lib/snet/addrutil/BUILD.bazel @@ -9,8 +9,8 @@ go_library( "//go/lib/addr:go_default_library", "//go/lib/common:go_default_library", "//go/lib/ctrl/seg:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/snet:go_default_library", "//go/lib/spath:go_default_library", - "//go/lib/topology:go_default_library", ], ) diff --git a/go/lib/snet/addrutil/addrutil.go b/go/lib/snet/addrutil/addrutil.go index bb8abf96b0..45d5ec1008 100644 --- a/go/lib/snet/addrutil/addrutil.go +++ b/go/lib/snet/addrutil/addrutil.go @@ -21,39 +21,38 @@ import ( "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/infra/modules/itopo" "github.com/scionproto/scion/go/lib/snet" "github.com/scionproto/scion/go/lib/spath" - "github.com/scionproto/scion/go/lib/topology" ) // GetPath creates a path from the given segment and then creates a snet.Addr. -func GetPath(svc addr.HostSVC, ps *seg.PathSegment, topoProv topology.Provider) (net.Addr, error) { - +func GetPath(svc addr.HostSVC, ps *seg.PathSegment, topoProv itopo.ProviderI) (net.Addr, error) { x := &bytes.Buffer{} if _, err := ps.RawWriteTo(x); err != nil { - return nil, common.NewBasicError("Failed to write segment to buffer", err) + return nil, common.NewBasicError("failed to write segment to buffer", err) } p := spath.New(x.Bytes()) if err := p.Reverse(); err != nil { - return nil, common.NewBasicError("Failed to reverse path", err) + return nil, common.NewBasicError("failed to reverse path", err) } if err := p.InitOffsets(); err != nil { - return nil, common.NewBasicError("Failed to init offsets", err) + return nil, common.NewBasicError("failed to init offsets", err) } hopF, err := p.GetHopField(p.HopOff) if err != nil { - return nil, common.NewBasicError("Failed to extract first HopField", err, "p", p) + return nil, common.NewBasicError("failed to extract first HopField", err, "p", p) } topo := topoProv.Get() - ifId := hopF.ConsIngress - ifInfo, ok := topo.IFInfoMap[ifId] + ifID := hopF.ConsIngress + overlayNextHop, ok := topo.OverlayNextHop2(ifID) if !ok { - return nil, common.NewBasicError("Unable to find first-hop BR for path", nil, "ifId", ifId) + return nil, common.NewBasicError("unable to find first-hop BR for path", nil, "ifID", ifID) } return &snet.Addr{ IA: ps.FirstIA(), Host: addr.NewSVCUDPAppAddr(svc), Path: p, - NextHop: ifInfo.InternalAddrs.PublicOverlay(topo.Overlay), + NextHop: overlayNextHop, }, nil } diff --git a/go/lib/xtest/BUILD.bazel b/go/lib/xtest/BUILD.bazel index f18a9a9270..cde4c66642 100644 --- a/go/lib/xtest/BUILD.bazel +++ b/go/lib/xtest/BUILD.bazel @@ -6,7 +6,6 @@ go_library( "convey.go", "helpers.go", "mocking.go", - "topo.go", "waiter.go", ], importpath = "github.com/scionproto/scion/go/lib/xtest", @@ -14,7 +13,6 @@ go_library( deps = [ "//go/lib/addr:go_default_library", "//go/lib/common:go_default_library", - "//go/lib/topology:go_default_library", "@com_github_smartystreets_goconvey//convey:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", ], diff --git a/go/path_srv/BUILD.bazel b/go/path_srv/BUILD.bazel index 8139e94568..bd0a20132b 100644 --- a/go/path_srv/BUILD.bazel +++ b/go/path_srv/BUILD.bazel @@ -25,7 +25,6 @@ go_library( "//go/lib/periodic:go_default_library", "//go/lib/prom:go_default_library", "//go/lib/revcache:go_default_library", - "//go/lib/topology:go_default_library", "//go/path_srv/internal/config:go_default_library", "//go/path_srv/internal/cryptosyncer:go_default_library", "//go/path_srv/internal/handlers:go_default_library", diff --git a/go/path_srv/internal/handlers/BUILD.bazel b/go/path_srv/internal/handlers/BUILD.bazel index 7d9566ccf3..8800587da1 100644 --- a/go/path_srv/internal/handlers/BUILD.bazel +++ b/go/path_srv/internal/handlers/BUILD.bazel @@ -20,6 +20,7 @@ go_library( "//go/lib/ctrl/seg:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/messenger:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/infra/modules/segfetcher:go_default_library", "//go/lib/infra/modules/seghandler:go_default_library", "//go/lib/infra/modules/segverifier:go_default_library", @@ -28,7 +29,6 @@ go_library( "//go/lib/pathdb/query:go_default_library", "//go/lib/revcache:go_default_library", "//go/lib/snet:go_default_library", - "//go/lib/topology:go_default_library", "//go/path_srv/internal/metrics:go_default_library", "//go/proto:go_default_library", "@com_github_opentracing_opentracing_go//:go_default_library", diff --git a/go/path_srv/internal/handlers/common.go b/go/path_srv/internal/handlers/common.go index bc5a10d74a..f868c0fbd0 100644 --- a/go/path_srv/internal/handlers/common.go +++ b/go/path_srv/internal/handlers/common.go @@ -24,11 +24,11 @@ import ( "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/ctrl/seg" "github.com/scionproto/scion/go/lib/infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/infra/modules/segfetcher" "github.com/scionproto/scion/go/lib/pathdb" "github.com/scionproto/scion/go/lib/pathdb/query" "github.com/scionproto/scion/go/lib/revcache" - "github.com/scionproto/scion/go/lib/topology" ) const ( @@ -43,7 +43,7 @@ type HandlerArgs struct { VerifierFactory infra.VerificationFactory QueryInterval time.Duration IA addr.IA - TopoProvider topology.Provider + TopoProvider itopo.ProviderI SegRequestAPI segfetcher.RequestAPI } @@ -53,7 +53,7 @@ type baseHandler struct { revCache revcache.RevCache inspector infra.ASInspector verifierFactory infra.VerificationFactory - topoProvider topology.Provider + topoProvider itopo.ProviderI retryInt time.Duration queryInt time.Duration } diff --git a/go/path_srv/internal/segreq/BUILD.bazel b/go/path_srv/internal/segreq/BUILD.bazel index 313160ef5f..96f317f087 100644 --- a/go/path_srv/internal/segreq/BUILD.bazel +++ b/go/path_srv/internal/segreq/BUILD.bazel @@ -20,6 +20,7 @@ go_library( "//go/lib/ctrl/seg:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/messenger:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/infra/modules/segfetcher:go_default_library", "//go/lib/log:go_default_library", "//go/lib/pathdb:go_default_library", @@ -27,7 +28,6 @@ go_library( "//go/lib/revcache:go_default_library", "//go/lib/serrors:go_default_library", "//go/lib/snet/addrutil:go_default_library", - "//go/lib/topology:go_default_library", "//go/path_srv/internal/handlers:go_default_library", "//go/path_srv/internal/metrics:go_default_library", "//go/proto:go_default_library", diff --git a/go/path_srv/internal/segreq/handler.go b/go/path_srv/internal/segreq/handler.go index 7f4094063b..c1d55edeca 100644 --- a/go/path_srv/internal/segreq/handler.go +++ b/go/path_srv/internal/segreq/handler.go @@ -36,7 +36,7 @@ type handler struct { } func NewHandler(args handlers.HandlerArgs) infra.Handler { - core := args.TopoProvider.Get().Core + core := args.TopoProvider.Get().Core() args.PathDB = createPathDB(args, core) return &handler{ fetcher: segfetcher.FetcherConfig{ diff --git a/go/path_srv/internal/segreq/provider.go b/go/path_srv/internal/segreq/provider.go index fcb78a3426..088f46acf9 100644 --- a/go/path_srv/internal/segreq/provider.go +++ b/go/path_srv/internal/segreq/provider.go @@ -24,13 +24,13 @@ import ( "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/ctrl/seg" "github.com/scionproto/scion/go/lib/infra" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/infra/modules/segfetcher" "github.com/scionproto/scion/go/lib/pathdb" "github.com/scionproto/scion/go/lib/pathdb/query" "github.com/scionproto/scion/go/lib/revcache" "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/snet/addrutil" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/proto" ) @@ -71,7 +71,7 @@ type nonCoreDstProvider struct { coreChecker CoreChecker localIA addr.IA pathDB pathdb.PathDB - topoProvider topology.Provider + topoProvider itopo.ProviderI } // Dst provides the server to lookup the segment for the given request. @@ -120,7 +120,7 @@ type coreDstProvider struct { SegSelector localIA addr.IA pathDB pathdb.PathDB - topoProvider topology.Provider + topoProvider itopo.ProviderI } func (p *coreDstProvider) Dst(ctx context.Context, req segfetcher.Request) (net.Addr, error) { diff --git a/go/path_srv/internal/segsyncer/BUILD.bazel b/go/path_srv/internal/segsyncer/BUILD.bazel index 5acf97d778..eed8702dae 100644 --- a/go/path_srv/internal/segsyncer/BUILD.bazel +++ b/go/path_srv/internal/segsyncer/BUILD.bazel @@ -12,6 +12,7 @@ go_library( "//go/lib/ctrl/seg:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/messenger:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/log:go_default_library", "//go/lib/pathdb:go_default_library", "//go/lib/pathdb/query:go_default_library", @@ -19,7 +20,6 @@ go_library( "//go/lib/revcache:go_default_library", "//go/lib/serrors:go_default_library", "//go/lib/snet/addrutil:go_default_library", - "//go/lib/topology:go_default_library", "//go/path_srv/internal/handlers:go_default_library", "//go/path_srv/internal/metrics:go_default_library", "//go/proto:go_default_library", diff --git a/go/path_srv/internal/segsyncer/segsyncer.go b/go/path_srv/internal/segsyncer/segsyncer.go index 410d6a5eba..e8e6e72145 100644 --- a/go/path_srv/internal/segsyncer/segsyncer.go +++ b/go/path_srv/internal/segsyncer/segsyncer.go @@ -29,6 +29,7 @@ import ( "github.com/scionproto/scion/go/lib/ctrl/seg" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/messenger" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/pathdb" "github.com/scionproto/scion/go/lib/pathdb/query" @@ -36,7 +37,6 @@ import ( "github.com/scionproto/scion/go/lib/revcache" "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/snet/addrutil" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/path_srv/internal/handlers" "github.com/scionproto/scion/go/path_srv/internal/metrics" "github.com/scionproto/scion/go/proto" @@ -58,7 +58,7 @@ type SegSyncer struct { msger infra.Messenger dstIA addr.IA localIA addr.IA - topoProvider topology.Provider + topoProvider itopo.ProviderI repErrCnt int } diff --git a/go/path_srv/main.go b/go/path_srv/main.go index 9735aafb0e..74a103ff2d 100644 --- a/go/path_srv/main.go +++ b/go/path_srv/main.go @@ -44,7 +44,6 @@ import ( "github.com/scionproto/scion/go/lib/periodic" "github.com/scionproto/scion/go/lib/prom" "github.com/scionproto/scion/go/lib/revcache" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/path_srv/internal/config" "github.com/scionproto/scion/go/path_srv/internal/cryptosyncer" "github.com/scionproto/scion/go/path_srv/internal/handlers" @@ -106,14 +105,13 @@ func realMain() int { ServiceType: proto.ServiceType_ps, TopoProvider: itopo.Provider(), } - trustStore := trust.NewStore(trustDB, topo.ISD_AS, trustConf, log.Root()) + trustStore := trust.NewStore(trustDB, topo.IA(), trustConf, log.Root()) err = trustStore.LoadAuthoritativeCrypto(filepath.Join(cfg.General.ConfigDir, "certs")) if err != nil { log.Crit("Unable to load local crypto", "err", err) return 1 } - topoAddress := topo.PS.GetById(cfg.General.ID) - if topoAddress == nil { + if !topo.Exists(addr.SvcPS, cfg.General.ID) { log.Crit("Unable to find topo address") return 1 } @@ -125,9 +123,9 @@ func realMain() int { defer trCloser.Close() opentracing.SetGlobalTracer(tracer) nc := infraenv.NetworkConfig{ - IA: topo.ISD_AS, - Public: env.GetPublicSnetAddress(topo.ISD_AS, topoAddress), - Bind: env.GetBindSnetAddress(topo.ISD_AS, topoAddress), + IA: topo.IA(), + Public: topo.SPublicAddress(addr.SvcPS, cfg.General.ID), + Bind: topo.SBindAddress(addr.SvcPS, cfg.General.ID), SVC: addr.SvcPS, ReconnectToDispatcher: cfg.General.ReconnectToDispatcher, QUIC: infraenv.QUIC{ @@ -155,15 +153,14 @@ func realMain() int { ASInspector: trustStore, VerifierFactory: trustStore, QueryInterval: cfg.PS.QueryInterval.Duration, - IA: topo.ISD_AS, + IA: topo.IA(), TopoProvider: itopo.Provider(), SegRequestAPI: msger, } - core := topo.Core msger.AddHandler(infra.SegRequest, segreq.NewHandler(args)) msger.AddHandler(infra.SegReg, handlers.NewSegRegHandler(args)) msger.AddHandler(infra.IfStateInfos, handlers.NewIfStateInfoHandler(args)) - if cfg.PS.SegSync && core { + if cfg.PS.SegSync && topo.Core() { // Old down segment sync mechanism msger.AddHandler(infra.SegSync, handlers.NewSyncHandler(args)) } @@ -221,7 +218,7 @@ func (t *periodicTasks) Start() error { } t.running = true var err error - if cfg.PS.SegSync && itopo.Get().Core { + if cfg.PS.SegSync && itopo.Get().Core() { t.segSyncers, err = segsyncer.StartAll(t.args, t.msger) if err != nil { return common.NewBasicError("Unable to start seg syncer", err) @@ -273,11 +270,11 @@ func setup() error { return common.NewBasicError("Unable to validate config", err) } itopo.Init(cfg.General.ID, proto.ServiceType_ps, itopo.Callbacks{}) - topo, err := topology.LoadFromFile(cfg.General.Topology) + topo, err := itopo.LoadFromFile(cfg.General.Topology) if err != nil { return common.NewBasicError("Unable to load topology", err) } - if _, _, err := itopo.SetStatic(topo, false); err != nil { + if _, _, err := itopo.SetStatic(topo.Raw(), false); err != nil { return common.NewBasicError("Unable to set initial static topology", err) } infraenv.InitInfraEnvironment(cfg.General.Topology) diff --git a/go/sciond/BUILD.bazel b/go/sciond/BUILD.bazel index 81a59859f4..00496a54d8 100644 --- a/go/sciond/BUILD.bazel +++ b/go/sciond/BUILD.bazel @@ -24,7 +24,6 @@ go_library( "//go/lib/periodic:go_default_library", "//go/lib/prom:go_default_library", "//go/lib/revcache:go_default_library", - "//go/lib/topology:go_default_library", "//go/proto:go_default_library", "//go/sciond/internal/config:go_default_library", "//go/sciond/internal/fetcher:go_default_library", diff --git a/go/sciond/internal/fetcher/BUILD.bazel b/go/sciond/internal/fetcher/BUILD.bazel index 5255e383bc..b0d9906c34 100644 --- a/go/sciond/internal/fetcher/BUILD.bazel +++ b/go/sciond/internal/fetcher/BUILD.bazel @@ -13,9 +13,9 @@ go_library( "//go/lib/addr:go_default_library", "//go/lib/common:go_default_library", "//go/lib/ctrl/seg:go_default_library", - "//go/lib/hostinfo:go_default_library", "//go/lib/infra:go_default_library", "//go/lib/infra/modules/combinator:go_default_library", + "//go/lib/infra/modules/itopo:go_default_library", "//go/lib/infra/modules/segfetcher:go_default_library", "//go/lib/log:go_default_library", "//go/lib/pathdb:go_default_library", @@ -26,7 +26,6 @@ go_library( "//go/lib/serrors:go_default_library", "//go/lib/snet:go_default_library", "//go/lib/spath:go_default_library", - "//go/lib/topology:go_default_library", "//go/lib/util:go_default_library", "//go/sciond/internal/config:go_default_library", "//go/sciond/internal/metrics:go_default_library", diff --git a/go/sciond/internal/fetcher/fetcher.go b/go/sciond/internal/fetcher/fetcher.go index 0fd771be0c..8af9c085d5 100644 --- a/go/sciond/internal/fetcher/fetcher.go +++ b/go/sciond/internal/fetcher/fetcher.go @@ -25,9 +25,9 @@ import ( "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/hostinfo" "github.com/scionproto/scion/go/lib/infra" "github.com/scionproto/scion/go/lib/infra/modules/combinator" + "github.com/scionproto/scion/go/lib/infra/modules/itopo" "github.com/scionproto/scion/go/lib/infra/modules/segfetcher" "github.com/scionproto/scion/go/lib/log" "github.com/scionproto/scion/go/lib/pathdb" @@ -37,7 +37,6 @@ import ( "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/snet" "github.com/scionproto/scion/go/lib/spath" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/lib/util" "github.com/scionproto/scion/go/sciond/internal/config" "github.com/scionproto/scion/go/sciond/internal/metrics" @@ -55,16 +54,16 @@ type TrustStore interface { type Fetcher struct { pathDB pathdb.PathDB revocationCache revcache.RevCache - topoProvider topology.Provider + topoProvider itopo.ProviderI config config.SDConfig segfetcher *segfetcher.Fetcher } func NewFetcher(messenger infra.Messenger, pathDB pathdb.PathDB, trustStore TrustStore, - revCache revcache.RevCache, cfg config.SDConfig, topoProvider topology.Provider, + revCache revcache.RevCache, cfg config.SDConfig, topoProvider itopo.ProviderI, logger log.Logger) *Fetcher { - localIA := topoProvider.Get().ISD_AS + localIA := topoProvider.Get().IA() return &Fetcher{ pathDB: pathDB, revocationCache: revCache, @@ -101,7 +100,7 @@ func (f *Fetcher) GetPaths(ctx context.Context, req *sciond.PathReq, // received by the Fetcher. type fetcherHandler struct { *Fetcher - topology *topology.Topo + topology itopo.Topology logger log.Logger } @@ -121,9 +120,9 @@ func (f *fetcherHandler) GetPaths(ctx context.Context, req *sciond.PathReq, } // Check source if req.Src.IA().IsZero() { - req.Src = f.topology.ISD_AS.IAInt() + req.Src = f.topology.IA().IAInt() } - if !req.Src.IA().Equal(f.topology.ISD_AS) { + if !req.Src.IA().Equal(f.topology.IA()) { return f.buildSCIONDReply(nil, 0, sciond.ErrorBadSrcIA), common.NewBasicError("Bad source AS", nil, "ia", req.Src.IA()) } @@ -132,7 +131,7 @@ func (f *fetcherHandler) GetPaths(ctx context.Context, req *sciond.PathReq, return f.buildSCIONDReply(nil, 0, sciond.ErrorBadDstIA), common.NewBasicError("Bad destination AS", nil, "ia", req.Dst.IA()) } - if req.Dst.IA().Equal(f.topology.ISD_AS) { + if req.Dst.IA().Equal(f.topology.IA()) { return f.buildSCIONDReply(nil, 0, sciond.ErrorOk), nil } if req.Flags.Refresh { @@ -212,7 +211,7 @@ func (f *fetcherHandler) buildSCIONDReplyEntries(paths []*combinator.Path, { Path: &sciond.FwdPathMeta{ FwdPath: []byte{}, - Mtu: uint16(f.topology.MTU), + Mtu: f.topology.MTU(), Interfaces: []sciond.PathInterface{}, ExpTime: util.TimeToSecs(time.Now().Add(spath.MaxTTL * time.Second)), }, @@ -226,7 +225,7 @@ func (f *fetcherHandler) buildSCIONDReplyEntries(paths []*combinator.Path, // In-memory write should never fail panic(err) } - ifInfo, ok := f.topology.IFInfoMap[path.Interfaces[0].IfID] + hostInfo, ok := f.topology.OverlayNextHop(path.Interfaces[0].IfID) if !ok { f.logger.Warn("Unable to find first-hop BR for path", "ifid", path.Interfaces[0].IfID) continue @@ -238,7 +237,7 @@ func (f *fetcherHandler) buildSCIONDReplyEntries(paths []*combinator.Path, Interfaces: path.Interfaces, ExpTime: uint32(path.ComputeExpTime().Unix()), }, - HostInfo: hostinfo.FromTopoBRAddr(*ifInfo.InternalAddrs), + HostInfo: hostInfo, }) if maxPaths != 0 && len(entries) == int(maxPaths) { break @@ -277,12 +276,13 @@ func (f *fetcherHandler) filterRevokedPaths(ctx context.Context, } func (f *fetcherHandler) flushSegmentsWithFirstHopInterfaces(ctx context.Context) error { - intfs := make([]*query.IntfSpec, 0, len(f.topology.IFInfoMap)) - for ifid := range f.topology.IFInfoMap { - intfs = append(intfs, &query.IntfSpec{ - IA: f.topology.ISD_AS, - IfID: ifid, - }) + ifIDs := f.topology.InterfaceIDs() + intfs := make([]*query.IntfSpec, len(ifIDs)) + for i, ifID := range ifIDs { + intfs[i] = &query.IntfSpec{ + IA: f.topology.IA(), + IfID: ifID, + } } q := &query.Params{ Intfs: intfs, @@ -327,7 +327,7 @@ func (f *fetcherHandler) determineDsts(req *sciond.PathReq, wildcardDst := req.Dst.IA().A == 0 if wildcardDst { - isdLocal := req.Dst.IA().I == f.topology.ISD_AS.I + isdLocal := req.Dst.IA().I == f.topology.IA().I return wildcardDsts(wildcardDst, isdLocal, ups, cores) } return map[addr.IA]struct{}{req.Dst.IA(): {}} diff --git a/go/sciond/internal/servers/BUILD.bazel b/go/sciond/internal/servers/BUILD.bazel index 0dd523fe12..a63ad8314f 100644 --- a/go/sciond/internal/servers/BUILD.bazel +++ b/go/sciond/internal/servers/BUILD.bazel @@ -22,7 +22,6 @@ go_library( "//go/lib/sciond:go_default_library", "//go/lib/serrors:go_default_library", "//go/lib/sock/reliable:go_default_library", - "//go/lib/topology:go_default_library", "//go/lib/tracing:go_default_library", "//go/proto:go_default_library", "//go/sciond/internal/fetcher:go_default_library", diff --git a/go/sciond/internal/servers/handlers.go b/go/sciond/internal/servers/handlers.go index dc9ba44519..909b8921ee 100644 --- a/go/sciond/internal/servers/handlers.go +++ b/go/sciond/internal/servers/handlers.go @@ -30,7 +30,6 @@ import ( "github.com/scionproto/scion/go/lib/revcache" "github.com/scionproto/scion/go/lib/sciond" "github.com/scionproto/scion/go/lib/serrors" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/proto" "github.com/scionproto/scion/go/sciond/internal/fetcher" "github.com/scionproto/scion/go/sciond/internal/metrics" @@ -109,11 +108,11 @@ func (h *ASInfoRequestHandler) Handle(ctx context.Context, conn net.PacketConn, topo := itopo.Get() reqIA := pld.AsInfoReq.Isdas.IA() if reqIA.IsZero() { - reqIA = topo.ISD_AS + reqIA = topo.IA() } mtu := uint16(0) - if reqIA.Equal(topo.ISD_AS) { - mtu = uint16(topo.MTU) + if reqIA.Equal(topo.IA()) { + mtu = uint16(topo.MTU()) } var entries []sciond.ASInfoReplyEntry opts := infra.ASInspectorOpts{RequiredAttributes: []infra.Attribute{infra.Core}} @@ -163,23 +162,28 @@ func (h *IFInfoRequestHandler) Handle(ctx context.Context, conn net.PacketConn, topo := itopo.Get() if len(ifInfoRequest.IfIDs) == 0 { // Reply with all the IFIDs we know - for ifid, ifInfo := range topo.IFInfoMap { + for _, ifid := range topo.InterfaceIDs() { + hostInfo, ok := topo.OverlayNextHop(ifid) + if !ok { + logger.Info("Received IF Info Request, but IFID not found", "ifid", ifid) + continue + } ifInfoReply.RawEntries = append(ifInfoReply.RawEntries, sciond.IFInfoReplyEntry{ IfID: ifid, - HostInfo: hostinfo.FromTopoBRAddr(*ifInfo.InternalAddrs), + HostInfo: hostInfo, }) } } else { // Reply with only the IFIDs the client requested for _, ifid := range ifInfoRequest.IfIDs { - ifInfo, ok := topo.IFInfoMap[ifid] + hostInfo, ok := topo.OverlayNextHop(ifid) if !ok { logger.Info("Received IF Info Request, but IFID not found", "ifid", ifid) continue } ifInfoReply.RawEntries = append(ifInfoReply.RawEntries, sciond.IFInfoReplyEntry{ IfID: ifid, - HostInfo: hostinfo.FromTopoBRAddr(*ifInfo.InternalAddrs), + HostInfo: hostInfo, }) } } @@ -213,7 +217,7 @@ func (h *SVCInfoRequestHandler) Handle(ctx context.Context, conn net.PacketConn, topo := itopo.Get() for _, t := range svcInfoRequest.ServiceTypes { var hostInfos []hostinfo.Host - hostInfos = makeHostInfos(topo, t) + hostInfos = topo.MakeHostInfos(t) replyEntry := sciond.ServiceInfoReplyEntry{ ServiceType: t, Ttl: DefaultServiceTTL, @@ -235,20 +239,6 @@ func (h *SVCInfoRequestHandler) Handle(ctx context.Context, conn net.PacketConn, } } -func makeHostInfos(topo *topology.Topo, t proto.ServiceType) []hostinfo.Host { - var hostInfos []hostinfo.Host - addresses, err := topo.GetAllTopoAddrs(t) - if err != nil { - // FIXME(lukedirtwalker): inform client about this: - // see https://github.com/scionproto/scion/issues/1673 - return hostInfos - } - for _, a := range addresses { - hostInfos = append(hostInfos, hostinfo.FromTopoAddr(a)) - } - return hostInfos -} - // RevNotificationHandler represents the shared global state for the handling of all // RevNotification announcements. The SCIOND API spawns a goroutine with method Handle // for each RevNotification it receives. diff --git a/go/sciond/main.go b/go/sciond/main.go index 44be461c4f..2b31e3dc8f 100644 --- a/go/sciond/main.go +++ b/go/sciond/main.go @@ -43,7 +43,6 @@ import ( "github.com/scionproto/scion/go/lib/periodic" "github.com/scionproto/scion/go/lib/prom" "github.com/scionproto/scion/go/lib/revcache" - "github.com/scionproto/scion/go/lib/topology" "github.com/scionproto/scion/go/proto" "github.com/scionproto/scion/go/sciond/internal/config" "github.com/scionproto/scion/go/sciond/internal/fetcher" @@ -85,7 +84,7 @@ func realMain() int { log.Crit("Setup failed", "err", err) return 1 } - if err := startDiscovery(); err != nil { + if err := startDiscovery(cfg.Discovery); err != nil { log.Crit("Unable to start topology fetcher", "err", err) return 1 } @@ -103,7 +102,7 @@ func realMain() int { } defer trustDB.Close() trustConf := trust.Config{TopoProvider: itopo.Provider()} - trustStore := trust.NewStore(trustDB, itopo.Get().ISD_AS, trustConf, log.Root()) + trustStore := trust.NewStore(trustDB, itopo.Get().IA(), trustConf, log.Root()) err = trustStore.LoadAuthoritativeTRC(filepath.Join(cfg.General.ConfigDir, "certs")) if err != nil { log.Crit("Unable to load local TRC", "err", err) @@ -117,7 +116,7 @@ func realMain() int { defer trCloser.Close() opentracing.SetGlobalTracer(tracer) nc := infraenv.NetworkConfig{ - IA: itopo.Get().ISD_AS, + IA: itopo.Get().IA(), Public: cfg.SD.Public, Bind: cfg.SD.Bind, SVC: addr.SvcNone, @@ -198,23 +197,23 @@ func setupBasic() error { func setup() error { if err := cfg.Validate(); err != nil { - return common.NewBasicError("Unable to validate config", err) + return common.NewBasicError("unable to validate config", err) } itopo.Init("", proto.ServiceType_unset, itopo.Callbacks{}) - topo, err := topology.LoadFromFile(cfg.General.Topology) + topo, err := itopo.LoadFromFile(cfg.General.Topology) if err != nil { - return common.NewBasicError("Unable to load topology", err) + return common.NewBasicError("unable to load topology", err) } - if _, _, err := itopo.SetStatic(topo, false); err != nil { - return common.NewBasicError("Unable to set initial static topology", err) + if _, _, err := itopo.SetStatic(topo.Raw(), false); err != nil { + return common.NewBasicError("unable to set initial static topology", err) } infraenv.InitInfraEnvironment(cfg.General.Topology) return cfg.SD.CreateSocketDirs() } -func startDiscovery() error { +func startDiscovery(file idiscovery.Config) error { var err error - discRunners, err = idiscovery.StartRunners(cfg.Discovery, discovery.Default, + discRunners, err = idiscovery.StartRunners(file, discovery.Default, idiscovery.TopoHandlers{}, nil, "sd") return err }