From 9452847b362c688f8e83b6ac48ada3956ce27be0 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Mon, 21 Apr 2025 18:21:59 -0700 Subject: [PATCH 01/31] initial skeleton of core logic --- dv/dv/injection.go | 76 ++++++++++++++++++++++++++++++++++++++++++++ dv/dv/router.go | 12 +++++++ std/ndn/constants.go | 1 + 3 files changed, 89 insertions(+) create mode 100644 dv/dv/injection.go diff --git a/dv/dv/injection.go b/dv/dv/injection.go new file mode 100644 index 00000000..2b7c9b29 --- /dev/null +++ b/dv/dv/injection.go @@ -0,0 +1,76 @@ +package dv + +import ( + enc "github.com/named-data/ndnd/std/encoding" + "github.com/named-data/ndnd/std/log" + "github.com/named-data/ndnd/std/ndn" + spec "github.com/named-data/ndnd/std/ndn/spec_2022" +) + +func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { + // If there is no incoming face ID, we can't use this + if !args.IncomingFaceId.IsSet() { + log.Warn(dv, "Received Prefix Injection with no incoming face ID, ignoring") + return + } + + // Check if app param is present + if args.Interest.AppParam() == nil { + log.Warn(dv, "Received Prefix Injection with no AppParam, ignoring") + return + } + + // Decode Prefix Injection Object + // note: ReadData() will skip over any non-critical TLV arguments (StapledCertificate) + data, _ /*sigCov*/, err := spec.Spec{}.ReadData(enc.NewWireView(args.Interest.AppParam())) + if err != nil { + log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) + return + } + + // TODO: perform signature validation + if true { + // validation would be here + /* + if !valid || err != nil { + log.Warn(dv, "Failed to validate signature", "name", data.Name(), "valid", valid, "err", err) + return + } + */ + + dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap()) + } +} + +func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) { + if contentType, set := object.ContentType().Get(); !set || contentType != ndn.ContentTypePrefixInjection { + log.Warn(dv, "Prefix Injection Object does not have the correct content type", + "contentType", object.ContentType()) + return + } + + // TODO: reject already seen injections (using version) + var prefix enc.Name + found := false + + for i, c := range object.Name() { + if c.IsKeyword("inject") { + prefix = object.Name().Prefix(i) + found = true + break + } + } + + if !found { + log.Warn(dv, "Prefix Injection Object name not in correct format", "name", object.Name()) + return + } + + // TODO: parse content, get cost + cost := uint64(0) + dirty := dv.rib.Set(prefix, dv.config.RouterName(), cost) + + if dirty { + go dv.postUpdateRib() + } +} diff --git a/dv/dv/router.go b/dv/dv/router.go index 6c7fa6b3..dca7feff 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -235,6 +235,17 @@ func (dv *Router) register() (err error) { return err } + injectPrefix := enc.NewKeywordComponent("routing"). + Append(enc.NewKeywordComponent("inject")) + + err = dv.engine.AttachHandler(injectPrefix, + func(args ndn.InterestHandlerArgs) { + go dv.onInjection(args) + }) + if err != nil { + return err + } + // Register routes to forwarder pfxs := []enc.Name{ dv.config.AdvertisementSyncPrefix(), @@ -242,6 +253,7 @@ func (dv *Router) register() (err error) { dv.config.PrefixTableSyncPrefix(), dv.config.RouterDataPrefix(), dv.config.MgmtPrefix(), + injectPrefix, } for _, prefix := range pfxs { dv.nfdc.Exec(nfdc.NfdMgmtCmd{ diff --git a/std/ndn/constants.go b/std/ndn/constants.go index 0e72b66b..7e484d16 100644 --- a/std/ndn/constants.go +++ b/std/ndn/constants.go @@ -14,6 +14,7 @@ const ( ContentTypeManifest ContentType = 4 ContentTypePrefixAnnouncement ContentType = 5 ContentTypeEncapsulatedData ContentType = 6 + ContentTypePrefixInjection ContentType = 7 ContentTypeSigningKey ContentType = 9 ) From b46d76a02506c954dc088bcb55b36960f6011294 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 26 Apr 2025 17:23:00 -0700 Subject: [PATCH 02/31] add parsing and validation --- dv/config/config.go | 23 ++ dv/dv.sample.yml | 11 + dv/dv/injection.go | 52 ++++- dv/dv/router.go | 65 ++++-- std/ndn/mgmt_2022/definitions.go | 16 ++ std/ndn/mgmt_2022/zz_generated.go | 362 ++++++++++++++++++++++++++++++ 6 files changed, 505 insertions(+), 24 deletions(-) diff --git a/dv/config/config.go b/dv/config/config.go index e3610ed0..551c82ab 100644 --- a/dv/config/config.go +++ b/dv/config/config.go @@ -33,6 +33,12 @@ type Config struct { KeyChainUri string `json:"keychain"` // List of trust anchor full names. TrustAnchors []string `json:"trust_anchors"` + // Path to trust schema for prefix injection. + PrefixInjectionSchemaPath string `json:"prefix_injection_schema"` + // URI specifying KeyChain location for prefix injection verifier. + PrefixInjectionKeychainUri string `json:"prefix_injection_keychain"` + // List of trust anchor full names for prefix injection. + PrefixInjectionTrustAnchors []string `json:"prefix_injection_trust_anchors"` // List of permanent neighbors. Neighbors []Neighbor `json:"neighbors"` @@ -58,6 +64,8 @@ type Config struct { mgmtPrefix enc.Name // Trust anchor names trustAnchorsN []enc.Name + // Prefix Injection trust anchor names + prefixInjectionTrustAnchorsN []enc.Name } type Neighbor struct { @@ -79,6 +87,8 @@ func DefaultConfig() *Config { AdvertisementSyncInterval_ms: 5000, RouterDeadInterval_ms: 30000, KeyChainUri: "undefined", + PrefixInjectionSchemaPath: "insecure", + PrefixInjectionKeychainUri: "insecure", } } @@ -134,6 +144,15 @@ func (c *Config) Parse() (err error) { c.trustAnchorsN = append(c.trustAnchorsN, name) } + c.prefixInjectionTrustAnchorsN = make([]enc.Name, 0, len(c.PrefixInjectionTrustAnchors)) + for _, anchor := range c.PrefixInjectionTrustAnchors { + name, err := enc.NameFromStr(anchor) + if err != nil { + return err + } + c.prefixInjectionTrustAnchorsN = append(c.prefixInjectionTrustAnchorsN, name) + } + // Advertisement sync and data prefixes c.advSyncPfxN = enc.LOCALHOP. Append(c.networkNameN...). @@ -219,6 +238,10 @@ func (c *Config) TrustAnchorNames() []enc.Name { return c.trustAnchorsN } +func (c *Config) PrefixInjectionTrustAnchorNames() []enc.Name { + return c.prefixInjectionTrustAnchorsN +} + func (c *Config) SchemaBytes() []byte { return SchemaBytes } diff --git a/dv/dv.sample.yml b/dv/dv.sample.yml index 435dbe63..22813edd 100644 --- a/dv/dv.sample.yml +++ b/dv/dv.sample.yml @@ -12,6 +12,17 @@ dv: trust_anchors: - "/ndn/KEY/%27%C4%B2%2A%9F%7B%81%27/ndn/v=1651246789556" + # [optional] Trust schema for prefix injection + # - If "insecure" is specified, security is disabled + # - If "deny" is specified, the prefix injection handler will be turned off + # - Example: /absolute/path/to/schema.tlv + prefix_injection_schema: "insecure" + # [optional] Keychain URI for prefix injection + prefix_injection_keychain: "insecure" + # [optional] List of full names of all prefix injection trust anchors + # - There should be at least one trust anchor if the schema is not "insecure" or "deny" + prefix_injection_trust_anchors: [] + # [optional] List of permanent neighbors # Example with all options: # - uri: udp4://suns.cs.ucla.edu:6363 # required diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 2b7c9b29..02eb3683 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -1,9 +1,11 @@ package dv import ( + "github.com/named-data/ndnd/dv/config" enc "github.com/named-data/ndnd/std/encoding" "github.com/named-data/ndnd/std/log" "github.com/named-data/ndnd/std/ndn" + mgmt "github.com/named-data/ndnd/std/ndn/mgmt_2022" spec "github.com/named-data/ndnd/std/ndn/spec_2022" ) @@ -22,24 +24,28 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { // Decode Prefix Injection Object // note: ReadData() will skip over any non-critical TLV arguments (StapledCertificate) - data, _ /*sigCov*/, err := spec.Spec{}.ReadData(enc.NewWireView(args.Interest.AppParam())) + data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(args.Interest.AppParam())) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) return } - // TODO: perform signature validation - if true { - // validation would be here - /* + // Validate signature + // TODO: use stapled certificates + dv.prefixInjectionClient.ValidateExt(ndn.ValidateExtArgs{ + Data: data, + SigCovered: sigCov, + CertNextHop: args.IncomingFaceId, /* is this sensible? */ + Callback: func(valid bool, err error) { if !valid || err != nil { log.Warn(dv, "Failed to validate signature", "name", data.Name(), "valid", valid, "err", err) return } - */ - dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap()) - } + // TODO: need to add into FIB? Otherwise what to do with the incoming FaceId? + dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap()) + }, + }) } func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) { @@ -66,10 +72,34 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) { return } - // TODO: parse content, get cost - cost := uint64(0) - dirty := dv.rib.Set(prefix, dv.config.RouterName(), cost) + piWire := object.Content() + params, err := mgmt.ParsePrefixInjection(enc.NewWireView(piWire), true) + if err != nil { + log.Warn(dv, "Failed to parse prefix injection object", "err", err) + return + } + var cost uint64 + if params.ExpirationPeriod < 0 { + log.Warn(dv, "Invalid ExpirationPeriod value", "ExpirationPeriod", params.ExpirationPeriod) + return + } else if params.ExpirationPeriod == 0 { + // Remove the RIB entry + // TODO: do it the proper way + cost = config.CostInfinity + } else { + // Add or update RIB entry + cost = params.Cost.GetOr(0) + if cost < 0 { + log.Warn(dv, "Invalid Cost value", "Cost", cost) + return + } + } + + dv.mutex.Lock() + defer dv.mutex.Unlock() + + dirty := dv.rib.Set(prefix, dv.config.RouterName(), cost) if dirty { go dv.postUpdateRib() } diff --git a/dv/dv/router.go b/dv/dv/router.go index dca7feff..586555ac 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -1,6 +1,7 @@ package dv import ( + "os" "sync" "time" @@ -31,6 +32,10 @@ type Router struct { trust *sec.TrustConfig // object client client ndn.Client + // whether to do prefix injection + enablePrefixInjection bool + // prefix injection client + prefixInjectionClient ndn.Client // nfd management thread nfdc *nfdc.NfdMgmtThread // single mutex for all operations @@ -92,14 +97,43 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { } } + enablePrefixInjection := config.PrefixInjectionSchemaPath != "deny" + prefixInjectionStore := object.NewMemoryStore() + var prefixInjectionTrust *sec.TrustConfig = nil + if !enablePrefixInjection { + log.Warn(nil, "Prefix injection is disabled") + } else if config.PrefixInjectionSchemaPath == "insecure" || config.PrefixInjectionKeychainUri == "insecure" { + log.Warn(nil, "Prefix injection module is in allow-all mode") + } else { + kc, err := keychain.NewKeyChain(config.PrefixInjectionKeychainUri, prefixInjectionStore) + if err != nil { + return nil, err + } + schemaData, err := os.ReadFile(config.PrefixInjectionSchemaPath) + if err != nil { + return nil, err + } + schema, err := trust_schema.NewLvsSchema(schemaData) + if err != nil { + return nil, err + } + anchors := config.TrustAnchorNames() + prefixInjectionTrust, err = sec.NewTrustConfig(kc, schema, anchors) + if err != nil { + return nil, err + } + } + // Create the DV router dv := &Router{ - engine: engine, - config: config, - trust: trust, - client: object.NewClient(engine, store, trust), - nfdc: nfdc.NewNfdMgmtThread(engine), - mutex: sync.Mutex{}, + engine: engine, + config: config, + trust: trust, + client: object.NewClient(engine, store, trust), + enablePrefixInjection: enablePrefixInjection, + prefixInjectionClient: object.NewClient(engine, prefixInjectionStore, prefixInjectionTrust), + nfdc: nfdc.NewNfdMgmtThread(engine), + mutex: sync.Mutex{}, } // Initialize advertisement module @@ -238,12 +272,14 @@ func (dv *Router) register() (err error) { injectPrefix := enc.NewKeywordComponent("routing"). Append(enc.NewKeywordComponent("inject")) - err = dv.engine.AttachHandler(injectPrefix, - func(args ndn.InterestHandlerArgs) { - go dv.onInjection(args) - }) - if err != nil { - return err + if dv.enablePrefixInjection { + err = dv.engine.AttachHandler(injectPrefix, + func(args ndn.InterestHandlerArgs) { + go dv.onInjection(args) + }) + if err != nil { + return err + } } // Register routes to forwarder @@ -253,8 +289,11 @@ func (dv *Router) register() (err error) { dv.config.PrefixTableSyncPrefix(), dv.config.RouterDataPrefix(), dv.config.MgmtPrefix(), - injectPrefix, } + if dv.enablePrefixInjection { + pfxs = append(pfxs, injectPrefix) + } + for _, prefix := range pfxs { dv.nfdc.Exec(nfdc.NfdMgmtCmd{ Module: "rib", diff --git a/std/ndn/mgmt_2022/definitions.go b/std/ndn/mgmt_2022/definitions.go index c438b7b4..3bcdd168 100644 --- a/std/ndn/mgmt_2022/definitions.go +++ b/std/ndn/mgmt_2022/definitions.go @@ -337,3 +337,19 @@ type CsQuery struct { PacketSize uint64 FreshnessPeriod uint64 } + +type ValidityPeriod struct { + //+field:string + NotBefore string `tlv:"0xfe"` + //+field:string + NotAfter string `tlv:"0xff"` +} + +type PrefixInjection struct { + //+field:natural + ExpirationPeriod uint64 `tlv:"0x6d"` + //+field:struct:ValidityPeriod + ValidityPeriod *ValidityPeriod `tlv:"0xfd"` + //+field:natural:optional + Cost optional.Optional[uint64] `tlv:"0x6a"` +} diff --git a/std/ndn/mgmt_2022/zz_generated.go b/std/ndn/mgmt_2022/zz_generated.go index 52b501e7..65d5302e 100644 --- a/std/ndn/mgmt_2022/zz_generated.go +++ b/std/ndn/mgmt_2022/zz_generated.go @@ -2,6 +2,7 @@ package mgmt_2022 import ( + "encoding/binary" "io" "strings" "time" @@ -6460,3 +6461,364 @@ func ParseCsInfoMsg(reader enc.WireView, ignoreCritical bool) (*CsInfoMsg, error context.Init() return context.Parse(reader, ignoreCritical) } + +type ValidityPeriodEncoder struct { + length uint +} + +type ValidityPeriodParsingContext struct { +} + +func (encoder *ValidityPeriodEncoder) Init(value *ValidityPeriod) { + + l := uint(0) + l += 3 + l += uint(enc.TLNum(len(value.NotBefore)).EncodingLength()) + l += uint(len(value.NotBefore)) + l += 3 + l += uint(enc.TLNum(len(value.NotAfter)).EncodingLength()) + l += uint(len(value.NotAfter)) + encoder.length = l + +} + +func (context *ValidityPeriodParsingContext) Init() { + +} + +func (encoder *ValidityPeriodEncoder) EncodeInto(value *ValidityPeriod, buf []byte) { + + pos := uint(0) + + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(254)) + pos += 3 + pos += uint(enc.TLNum(len(value.NotBefore)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.NotBefore) + pos += uint(len(value.NotBefore)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(255)) + pos += 3 + pos += uint(enc.TLNum(len(value.NotAfter)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.NotAfter) + pos += uint(len(value.NotAfter)) +} + +func (encoder *ValidityPeriodEncoder) Encode(value *ValidityPeriod) enc.Wire { + + wire := make(enc.Wire, 1) + wire[0] = make([]byte, encoder.length) + buf := wire[0] + encoder.EncodeInto(value, buf) + + return wire +} + +func (context *ValidityPeriodParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*ValidityPeriod, error) { + + var handled_NotBefore bool = false + var handled_NotAfter bool = false + + progress := -1 + _ = progress + + value := &ValidityPeriod{} + var err error + var startPos int + for { + startPos = reader.Pos() + if startPos >= reader.Length() { + break + } + typ := enc.TLNum(0) + l := enc.TLNum(0) + typ, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + l, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + + err = nil + if handled := false; true { + switch typ { + case 254: + if true { + handled = true + handled_NotBefore = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.NotBefore = builder.String() + } + } + } + case 255: + if true { + handled = true + handled_NotAfter = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.NotAfter = builder.String() + } + } + } + default: + if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { + return nil, enc.ErrUnrecognizedField{TypeNum: typ} + } + handled = true + err = reader.Skip(int(l)) + } + if err == nil && !handled { + } + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} + } + } + } + + startPos = reader.Pos() + err = nil + + if !handled_NotBefore && err == nil { + err = enc.ErrSkipRequired{Name: "NotBefore", TypeNum: 254} + } + if !handled_NotAfter && err == nil { + err = enc.ErrSkipRequired{Name: "NotAfter", TypeNum: 255} + } + + if err != nil { + return nil, err + } + + return value, nil +} + +func (value *ValidityPeriod) Encode() enc.Wire { + encoder := ValidityPeriodEncoder{} + encoder.Init(value) + return encoder.Encode(value) +} + +func (value *ValidityPeriod) Bytes() []byte { + return value.Encode().Join() +} + +func ParseValidityPeriod(reader enc.WireView, ignoreCritical bool) (*ValidityPeriod, error) { + context := ValidityPeriodParsingContext{} + context.Init() + return context.Parse(reader, ignoreCritical) +} + +type PrefixInjectionEncoder struct { + length uint + + ValidityPeriod_encoder ValidityPeriodEncoder +} + +type PrefixInjectionParsingContext struct { + ValidityPeriod_context ValidityPeriodParsingContext +} + +func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { + + if value.ValidityPeriod != nil { + encoder.ValidityPeriod_encoder.Init(value.ValidityPeriod) + } + + l := uint(0) + l += 1 + l += uint(1 + enc.Nat(value.ExpirationPeriod).EncodingLength()) + if value.ValidityPeriod != nil { + l += 3 + l += uint(enc.TLNum(encoder.ValidityPeriod_encoder.length).EncodingLength()) + l += encoder.ValidityPeriod_encoder.length + } + if optval, ok := value.Cost.Get(); ok { + l += 1 + l += uint(1 + enc.Nat(optval).EncodingLength()) + } + encoder.length = l + +} + +func (context *PrefixInjectionParsingContext) Init() { + + context.ValidityPeriod_context.Init() + +} + +func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf []byte) { + + pos := uint(0) + + buf[pos] = byte(109) + pos += 1 + + buf[pos] = byte(enc.Nat(value.ExpirationPeriod).EncodeInto(buf[pos+1:])) + pos += uint(1 + buf[pos]) + if value.ValidityPeriod != nil { + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(253)) + pos += 3 + pos += uint(enc.TLNum(encoder.ValidityPeriod_encoder.length).EncodeInto(buf[pos:])) + if encoder.ValidityPeriod_encoder.length > 0 { + encoder.ValidityPeriod_encoder.EncodeInto(value.ValidityPeriod, buf[pos:]) + pos += encoder.ValidityPeriod_encoder.length + } + } + if optval, ok := value.Cost.Get(); ok { + buf[pos] = byte(106) + pos += 1 + + buf[pos] = byte(enc.Nat(optval).EncodeInto(buf[pos+1:])) + pos += uint(1 + buf[pos]) + + } +} + +func (encoder *PrefixInjectionEncoder) Encode(value *PrefixInjection) enc.Wire { + + wire := make(enc.Wire, 1) + wire[0] = make([]byte, encoder.length) + buf := wire[0] + encoder.EncodeInto(value, buf) + + return wire +} + +func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { + + var handled_ExpirationPeriod bool = false + var handled_ValidityPeriod bool = false + var handled_Cost bool = false + + progress := -1 + _ = progress + + value := &PrefixInjection{} + var err error + var startPos int + for { + startPos = reader.Pos() + if startPos >= reader.Length() { + break + } + typ := enc.TLNum(0) + l := enc.TLNum(0) + typ, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + l, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + + err = nil + if handled := false; true { + switch typ { + case 109: + if true { + handled = true + handled_ExpirationPeriod = true + value.ExpirationPeriod = uint64(0) + { + for i := 0; i < int(l); i++ { + x := byte(0) + x, err = reader.ReadByte() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + break + } + value.ExpirationPeriod = uint64(value.ExpirationPeriod<<8) | uint64(x) + } + } + } + case 253: + if true { + handled = true + handled_ValidityPeriod = true + value.ValidityPeriod, err = context.ValidityPeriod_context.Parse(reader.Delegate(int(l)), ignoreCritical) + } + case 106: + if true { + handled = true + handled_Cost = true + { + optval := uint64(0) + optval = uint64(0) + { + for i := 0; i < int(l); i++ { + x := byte(0) + x, err = reader.ReadByte() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + break + } + optval = uint64(optval<<8) | uint64(x) + } + } + value.Cost.Set(optval) + } + } + default: + if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { + return nil, enc.ErrUnrecognizedField{TypeNum: typ} + } + handled = true + err = reader.Skip(int(l)) + } + if err == nil && !handled { + } + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} + } + } + } + + startPos = reader.Pos() + err = nil + + if !handled_ExpirationPeriod && err == nil { + err = enc.ErrSkipRequired{Name: "ExpirationPeriod", TypeNum: 109} + } + if !handled_ValidityPeriod && err == nil { + value.ValidityPeriod = nil + } + if !handled_Cost && err == nil { + value.Cost.Unset() + } + + if err != nil { + return nil, err + } + + return value, nil +} + +func (value *PrefixInjection) Encode() enc.Wire { + encoder := PrefixInjectionEncoder{} + encoder.Init(value) + return encoder.Encode(value) +} + +func (value *PrefixInjection) Bytes() []byte { + return value.Encode().Join() +} + +func ParsePrefixInjection(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { + context := PrefixInjectionParsingContext{} + context.Init() + return context.Parse(reader, ignoreCritical) +} From 93f16c81f4344f2405025a6a10bb38573175e414 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 26 Apr 2025 18:50:57 -0700 Subject: [PATCH 03/31] also add into local forwarder --- dv/config/config.go | 1 + dv/dv/injection.go | 15 ++++++++++++++- std/ndn/mgmt_2022/route.go | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dv/config/config.go b/dv/config/config.go index 551c82ab..47fafb3f 100644 --- a/dv/config/config.go +++ b/dv/config/config.go @@ -11,6 +11,7 @@ import ( const CostInfinity = uint64(16) const NlsrOrigin = uint64(mgmt.RouteOriginNLSR) +const PrefixInjOrigin = uint64(mgmt.RouteOriginPrefixInj) var MulticastStrategy = enc.LOCALHOST. Append(enc.NewGenericComponent("nfd")). diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 02eb3683..fe9a5341 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -2,11 +2,13 @@ package dv import ( "github.com/named-data/ndnd/dv/config" + "github.com/named-data/ndnd/dv/nfdc" enc "github.com/named-data/ndnd/std/encoding" "github.com/named-data/ndnd/std/log" "github.com/named-data/ndnd/std/ndn" mgmt "github.com/named-data/ndnd/std/ndn/mgmt_2022" spec "github.com/named-data/ndnd/std/ndn/spec_2022" + "github.com/named-data/ndnd/std/types/optional" ) func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { @@ -42,7 +44,6 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } - // TODO: need to add into FIB? Otherwise what to do with the incoming FaceId? dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap()) }, }) @@ -96,6 +97,18 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) { } } + dv.nfdc.Exec(nfdc.NfdMgmtCmd{ + Module: "rib", + Cmd: "register", + Args: &mgmt.ControlArgs{ + Name: prefix, + FaceId: optional.Some(faceId), + Origin: optional.Some(config.PrefixInjOrigin), + Cost: optional.Some(cost), + }, + Retries: 3, + }) + dv.mutex.Lock() defer dv.mutex.Unlock() diff --git a/std/ndn/mgmt_2022/route.go b/std/ndn/mgmt_2022/route.go index fd29e957..f6aa7e7d 100644 --- a/std/ndn/mgmt_2022/route.go +++ b/std/ndn/mgmt_2022/route.go @@ -31,6 +31,7 @@ const ( RouteOriginStatic RouteOrigin = 255 RouteOriginNLSR RouteOrigin = 128 RouteOriginPrefixAnn RouteOrigin = 129 + RouteOriginPrefixInj RouteOrigin = 130 RouteOriginClient RouteOrigin = 65 RouteOriginAutoreg RouteOrigin = 64 RouteOriginAutoconf RouteOrigin = 66 From 21cc8e8871e8b0ecdbca1e1dc32b7830153a1844 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Mon, 28 Apr 2025 13:52:40 -0700 Subject: [PATCH 04/31] custom fetch --- dv/dv/injection.go | 17 +++++++++++++---- std/ndn/client.go | 3 +++ std/object/client_trust.go | 23 +++++++++++++---------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index fe9a5341..0135b18c 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -33,11 +33,20 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { } // Validate signature - // TODO: use stapled certificates dv.prefixInjectionClient.ValidateExt(ndn.ValidateExtArgs{ - Data: data, - SigCovered: sigCov, - CertNextHop: args.IncomingFaceId, /* is this sensible? */ + Data: data, + SigCovered: sigCov, + Fetch: optional.Some(func(name enc.Name, config *ndn.InterestConfig, callback ndn.ExpressCallbackFunc) { + // TODO: use stapled certificates + config.NextHopId = optional.None[uint64]() + dv.prefixInjectionClient.ExpressR(ndn.ExpressRArgs{ + Name: name, + Config: config, + Retries: 3, + Callback: callback, + TryStore: dv.prefixInjectionClient.Store(), + }) + }), Callback: func(valid bool, err error) { if !valid || err != nil { log.Warn(dv, "Failed to validate signature", "name", data.Name(), "valid", valid, "err", err) diff --git a/std/ndn/client.go b/std/ndn/client.go index f978408a..b99bc75e 100644 --- a/std/ndn/client.go +++ b/std/ndn/client.go @@ -161,6 +161,9 @@ type ValidateExtArgs struct { CertNextHop optional.Optional[uint64] // UseDataNameFwHint overrides trust config option. UseDataNameFwHint optional.Optional[bool] + // Fetch function to use for fetching certificates. + // The fetcher MUST check the store for the certificate before fetching. + Fetch optional.Optional[func(enc.Name, *InterestConfig, ExpressCallbackFunc)] } // Announcement are the arguments for the announce prefix API. diff --git a/std/object/client_trust.go b/std/object/client_trust.go index 3c0a5417..f5b7b9c7 100644 --- a/std/object/client_trust.go +++ b/std/object/client_trust.go @@ -40,22 +40,25 @@ func (c *Client) ValidateExt(args ndn.ValidateExtArgs) { overrideName = args.OverrideName } + // Default fetch function + fetch := args.Fetch.GetOr(func(name enc.Name, config *ndn.InterestConfig, callback ndn.ExpressCallbackFunc) { + config.NextHopId = args.CertNextHop + c.ExpressR(ndn.ExpressRArgs{ + Name: name, + Config: config, + Retries: 3, + Callback: callback, + TryStore: c.store, + }) + }) + c.trust.Validate(sec.TrustConfigValidateArgs{ Data: args.Data, DataSigCov: args.SigCovered, Callback: args.Callback, OverrideName: overrideName, UseDataNameFwHint: args.UseDataNameFwHint, - Fetch: func(name enc.Name, config *ndn.InterestConfig, callback ndn.ExpressCallbackFunc) { - config.NextHopId = args.CertNextHop - c.ExpressR(ndn.ExpressRArgs{ - Name: name, - Config: config, - Retries: 3, - Callback: callback, - TryStore: c.store, - }) - }, + Fetch: fetch, }) } From c4de1962347cd6e0d1f01e234eda335bfbfc7069 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Mon, 28 Apr 2025 18:38:49 -0700 Subject: [PATCH 05/31] use stapled certificates --- dv/dv/injection.go | 36 ++++- dv/dv/router.go | 4 +- std/ndn/mgmt_2022/definitions.go | 17 ++- std/ndn/mgmt_2022/zz_generated.go | 238 ++++++++++++++++++++---------- 4 files changed, 205 insertions(+), 90 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 0135b18c..51a4de0a 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -32,12 +32,44 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } + paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) + if err != nil { + log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) + return + } + + var stapledCertCallbacks []ndn.ExpressCallbackArgs + for _, certWire := range paParams.StapledCertificates { + data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(certWire)) + if err != nil { + log.Warn(dv, "Stapled malformed certificate", "err", err) + return + } + + stapledCertCallbacks = append(stapledCertCallbacks, + ndn.ExpressCallbackArgs{ + Result: ndn.InterestResultData, + Data: data, + RawData: certWire, + SigCovered: sigCov, + IsLocal: true, + }) + } + // Validate signature dv.prefixInjectionClient.ValidateExt(ndn.ValidateExtArgs{ Data: data, SigCovered: sigCov, Fetch: optional.Some(func(name enc.Name, config *ndn.InterestConfig, callback ndn.ExpressCallbackFunc) { - // TODO: use stapled certificates + for _, certCallback := range stapledCertCallbacks { + if certCallback.Data.Name().Equal(name) { + dv.prefixInjectionClient.Engine().Post(func() { + callback(certCallback) + }) + return + } + } + config.NextHopId = optional.None[uint64]() dv.prefixInjectionClient.ExpressR(ndn.ExpressRArgs{ Name: name, @@ -83,7 +115,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) { } piWire := object.Content() - params, err := mgmt.ParsePrefixInjection(enc.NewWireView(piWire), true) + params, err := mgmt.ParsePrefixInjectionInnerContent(enc.NewWireView(piWire), true) if err != nil { log.Warn(dv, "Failed to parse prefix injection object", "err", err) return diff --git a/dv/dv/router.go b/dv/dv/router.go index 3f43ec83..785508d0 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -102,7 +102,7 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { } enablePrefixInjection := config.PrefixInjectionSchemaPath != "deny" - prefixInjectionStore := object.NewMemoryStore() + prefixInjectionStore := storage.NewMemoryStore() var prefixInjectionTrust *sec.TrustConfig = nil if !enablePrefixInjection { log.Warn(nil, "Prefix injection is disabled") @@ -297,7 +297,7 @@ func (dv *Router) register() (err error) { if dv.enablePrefixInjection { pfxs = append(pfxs, injectPrefix) } - + for _, prefix := range pfxs { dv.nfdc.Exec(nfdc.NfdMgmtCmd{ Module: "rib", diff --git a/std/ndn/mgmt_2022/definitions.go b/std/ndn/mgmt_2022/definitions.go index 3bcdd168..b39f4b48 100644 --- a/std/ndn/mgmt_2022/definitions.go +++ b/std/ndn/mgmt_2022/definitions.go @@ -5,6 +5,7 @@ import ( "time" enc "github.com/named-data/ndnd/std/encoding" + "github.com/named-data/ndnd/std/ndn/spec_2022" "github.com/named-data/ndnd/std/types/optional" ) @@ -338,18 +339,18 @@ type CsQuery struct { FreshnessPeriod uint64 } -type ValidityPeriod struct { - //+field:string - NotBefore string `tlv:"0xfe"` - //+field:string - NotAfter string `tlv:"0xff"` +type PrefixInjection struct { + //+field:sequence:enc.Wire:wire + StapledCertificates []enc.Wire `tlv:"0x2d"` + //+field:wire + ObjectWire enc.Wire `tlv:"0x06"` } -type PrefixInjection struct { +type PrefixInjectionInnerContent struct { //+field:natural ExpirationPeriod uint64 `tlv:"0x6d"` - //+field:struct:ValidityPeriod - ValidityPeriod *ValidityPeriod `tlv:"0xfd"` + //+field:struct:spec_2022.ValidityPeriod + ValidityPeriod *spec_2022.ValidityPeriod `tlv:"0xfd"` //+field:natural:optional Cost optional.Optional[uint64] `tlv:"0x6a"` } diff --git a/std/ndn/mgmt_2022/zz_generated.go b/std/ndn/mgmt_2022/zz_generated.go index 324f4ffd..e0b6f2bb 100644 --- a/std/ndn/mgmt_2022/zz_generated.go +++ b/std/ndn/mgmt_2022/zz_generated.go @@ -9,6 +9,7 @@ import ( "time" enc "github.com/named-data/ndnd/std/encoding" + "github.com/named-data/ndnd/std/ndn/spec_2022" ) type StrategyEncoder struct { @@ -6463,67 +6464,146 @@ func ParseCsInfoMsg(reader enc.WireView, ignoreCritical bool) (*CsInfoMsg, error return context.Parse(reader, ignoreCritical) } -type ValidityPeriodEncoder struct { - length uint +type PrefixInjectionEncoder struct { + Length uint + + StapledCertificates_subencoder []struct { + StapledCertificates_length uint + } + ObjectWire_length uint } -type ValidityPeriodParsingContext struct { +type PrefixInjectionParsingContext struct { } -func (encoder *ValidityPeriodEncoder) Init(value *ValidityPeriod) { +func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { + { + StapledCertificates_l := len(value.StapledCertificates) + encoder.StapledCertificates_subencoder = make([]struct { + StapledCertificates_length uint + }, StapledCertificates_l) + for i := 0; i < StapledCertificates_l; i++ { + pseudoEncoder := &encoder.StapledCertificates_subencoder[i] + pseudoValue := struct { + StapledCertificates enc.Wire + }{ + StapledCertificates: value.StapledCertificates[i], + } + { + encoder := pseudoEncoder + value := &pseudoValue + if value.StapledCertificates != nil { + encoder.StapledCertificates_length = 0 + for _, c := range value.StapledCertificates { + encoder.StapledCertificates_length += uint(len(c)) + } + } + _ = encoder + _ = value + } + } + } + if value.ObjectWire != nil { + encoder.ObjectWire_length = 0 + for _, c := range value.ObjectWire { + encoder.ObjectWire_length += uint(len(c)) + } + } l := uint(0) - l += 3 - l += uint(enc.TLNum(len(value.NotBefore)).EncodingLength()) - l += uint(len(value.NotBefore)) - l += 3 - l += uint(enc.TLNum(len(value.NotAfter)).EncodingLength()) - l += uint(len(value.NotAfter)) - encoder.length = l + if value.StapledCertificates != nil { + for seq_i, seq_v := range value.StapledCertificates { + pseudoEncoder := &encoder.StapledCertificates_subencoder[seq_i] + pseudoValue := struct { + StapledCertificates enc.Wire + }{ + StapledCertificates: seq_v, + } + { + encoder := pseudoEncoder + value := &pseudoValue + if value.StapledCertificates != nil { + l += 1 + l += uint(enc.TLNum(encoder.StapledCertificates_length).EncodingLength()) + l += encoder.StapledCertificates_length + } + _ = encoder + _ = value + } + } + } + if value.ObjectWire != nil { + l += 1 + l += uint(enc.TLNum(encoder.ObjectWire_length).EncodingLength()) + l += encoder.ObjectWire_length + } + encoder.Length = l } -func (context *ValidityPeriodParsingContext) Init() { +func (context *PrefixInjectionParsingContext) Init() { } -func (encoder *ValidityPeriodEncoder) EncodeInto(value *ValidityPeriod, buf []byte) { +func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf []byte) { pos := uint(0) - buf[pos] = 253 - binary.BigEndian.PutUint16(buf[pos+1:], uint16(254)) - pos += 3 - pos += uint(enc.TLNum(len(value.NotBefore)).EncodeInto(buf[pos:])) - copy(buf[pos:], value.NotBefore) - pos += uint(len(value.NotBefore)) - buf[pos] = 253 - binary.BigEndian.PutUint16(buf[pos+1:], uint16(255)) - pos += 3 - pos += uint(enc.TLNum(len(value.NotAfter)).EncodeInto(buf[pos:])) - copy(buf[pos:], value.NotAfter) - pos += uint(len(value.NotAfter)) + if value.StapledCertificates != nil { + for seq_i, seq_v := range value.StapledCertificates { + pseudoEncoder := &encoder.StapledCertificates_subencoder[seq_i] + pseudoValue := struct { + StapledCertificates enc.Wire + }{ + StapledCertificates: seq_v, + } + { + encoder := pseudoEncoder + value := &pseudoValue + if value.StapledCertificates != nil { + buf[pos] = byte(45) + pos += 1 + pos += uint(enc.TLNum(encoder.StapledCertificates_length).EncodeInto(buf[pos:])) + for _, w := range value.StapledCertificates { + copy(buf[pos:], w) + pos += uint(len(w)) + } + } + _ = encoder + _ = value + } + } + } + if value.ObjectWire != nil { + buf[pos] = byte(6) + pos += 1 + pos += uint(enc.TLNum(encoder.ObjectWire_length).EncodeInto(buf[pos:])) + for _, w := range value.ObjectWire { + copy(buf[pos:], w) + pos += uint(len(w)) + } + } } -func (encoder *ValidityPeriodEncoder) Encode(value *ValidityPeriod) enc.Wire { +func (encoder *PrefixInjectionEncoder) Encode(value *PrefixInjection) enc.Wire { wire := make(enc.Wire, 1) - wire[0] = make([]byte, encoder.length) + wire[0] = make([]byte, encoder.Length) buf := wire[0] encoder.EncodeInto(value, buf) return wire } -func (context *ValidityPeriodParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*ValidityPeriod, error) { +func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { - var handled_NotBefore bool = false - var handled_NotAfter bool = false + var handled_StapledCertificates bool = false + var handled_ObjectWire bool = false progress := -1 _ = progress - value := &ValidityPeriod{} + value := &PrefixInjection{} var err error var startPos int for { @@ -6545,29 +6625,31 @@ func (context *ValidityPeriodParsingContext) Parse(reader enc.WireView, ignoreCr err = nil if handled := false; true { switch typ { - case 254: + case 45: if true { handled = true - handled_NotBefore = true + handled_StapledCertificates = true + if value.StapledCertificates == nil { + value.StapledCertificates = make([]enc.Wire, 0) + } { - var builder strings.Builder - _, err = reader.CopyN(&builder, int(l)) - if err == nil { - value.NotBefore = builder.String() + pseudoValue := struct { + StapledCertificates enc.Wire + }{} + { + value := &pseudoValue + value.StapledCertificates, err = reader.ReadWire(int(l)) + _ = value } + value.StapledCertificates = append(value.StapledCertificates, pseudoValue.StapledCertificates) } + progress-- } - case 255: + case 6: if true { handled = true - handled_NotAfter = true - { - var builder strings.Builder - _, err = reader.CopyN(&builder, int(l)) - if err == nil { - value.NotAfter = builder.String() - } - } + handled_ObjectWire = true + value.ObjectWire, err = reader.ReadWire(int(l)) } default: if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { @@ -6587,11 +6669,11 @@ func (context *ValidityPeriodParsingContext) Parse(reader enc.WireView, ignoreCr startPos = reader.Pos() err = nil - if !handled_NotBefore && err == nil { - err = enc.ErrSkipRequired{Name: "NotBefore", TypeNum: 254} + if !handled_StapledCertificates && err == nil { + // sequence - skip } - if !handled_NotAfter && err == nil { - err = enc.ErrSkipRequired{Name: "NotAfter", TypeNum: 255} + if !handled_ObjectWire && err == nil { + value.ObjectWire = nil } if err != nil { @@ -6601,33 +6683,33 @@ func (context *ValidityPeriodParsingContext) Parse(reader enc.WireView, ignoreCr return value, nil } -func (value *ValidityPeriod) Encode() enc.Wire { - encoder := ValidityPeriodEncoder{} +func (value *PrefixInjection) Encode() enc.Wire { + encoder := PrefixInjectionEncoder{} encoder.Init(value) return encoder.Encode(value) } -func (value *ValidityPeriod) Bytes() []byte { +func (value *PrefixInjection) Bytes() []byte { return value.Encode().Join() } -func ParseValidityPeriod(reader enc.WireView, ignoreCritical bool) (*ValidityPeriod, error) { - context := ValidityPeriodParsingContext{} +func ParsePrefixInjection(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { + context := PrefixInjectionParsingContext{} context.Init() return context.Parse(reader, ignoreCritical) } -type PrefixInjectionEncoder struct { - length uint +type PrefixInjectionInnerContentEncoder struct { + Length uint - ValidityPeriod_encoder ValidityPeriodEncoder + ValidityPeriod_encoder spec_2022.ValidityPeriodEncoder } -type PrefixInjectionParsingContext struct { - ValidityPeriod_context ValidityPeriodParsingContext +type PrefixInjectionInnerContentParsingContext struct { + ValidityPeriod_context spec_2022.ValidityPeriodParsingContext } -func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { +func (encoder *PrefixInjectionInnerContentEncoder) Init(value *PrefixInjectionInnerContent) { if value.ValidityPeriod != nil { encoder.ValidityPeriod_encoder.Init(value.ValidityPeriod) @@ -6638,24 +6720,24 @@ func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { l += uint(1 + enc.Nat(value.ExpirationPeriod).EncodingLength()) if value.ValidityPeriod != nil { l += 3 - l += uint(enc.TLNum(encoder.ValidityPeriod_encoder.length).EncodingLength()) - l += encoder.ValidityPeriod_encoder.length + l += uint(enc.TLNum(encoder.ValidityPeriod_encoder.Length).EncodingLength()) + l += encoder.ValidityPeriod_encoder.Length } if optval, ok := value.Cost.Get(); ok { l += 1 l += uint(1 + enc.Nat(optval).EncodingLength()) } - encoder.length = l + encoder.Length = l } -func (context *PrefixInjectionParsingContext) Init() { +func (context *PrefixInjectionInnerContentParsingContext) Init() { context.ValidityPeriod_context.Init() } -func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf []byte) { +func (encoder *PrefixInjectionInnerContentEncoder) EncodeInto(value *PrefixInjectionInnerContent, buf []byte) { pos := uint(0) @@ -6668,10 +6750,10 @@ func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf [] buf[pos] = 253 binary.BigEndian.PutUint16(buf[pos+1:], uint16(253)) pos += 3 - pos += uint(enc.TLNum(encoder.ValidityPeriod_encoder.length).EncodeInto(buf[pos:])) - if encoder.ValidityPeriod_encoder.length > 0 { + pos += uint(enc.TLNum(encoder.ValidityPeriod_encoder.Length).EncodeInto(buf[pos:])) + if encoder.ValidityPeriod_encoder.Length > 0 { encoder.ValidityPeriod_encoder.EncodeInto(value.ValidityPeriod, buf[pos:]) - pos += encoder.ValidityPeriod_encoder.length + pos += encoder.ValidityPeriod_encoder.Length } } if optval, ok := value.Cost.Get(); ok { @@ -6684,17 +6766,17 @@ func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf [] } } -func (encoder *PrefixInjectionEncoder) Encode(value *PrefixInjection) enc.Wire { +func (encoder *PrefixInjectionInnerContentEncoder) Encode(value *PrefixInjectionInnerContent) enc.Wire { wire := make(enc.Wire, 1) - wire[0] = make([]byte, encoder.length) + wire[0] = make([]byte, encoder.Length) buf := wire[0] encoder.EncodeInto(value, buf) return wire } -func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { +func (context *PrefixInjectionInnerContentParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { var handled_ExpirationPeriod bool = false var handled_ValidityPeriod bool = false @@ -6703,7 +6785,7 @@ func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreC progress := -1 _ = progress - value := &PrefixInjection{} + value := &PrefixInjectionInnerContent{} var err error var startPos int for { @@ -6808,18 +6890,18 @@ func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreC return value, nil } -func (value *PrefixInjection) Encode() enc.Wire { - encoder := PrefixInjectionEncoder{} +func (value *PrefixInjectionInnerContent) Encode() enc.Wire { + encoder := PrefixInjectionInnerContentEncoder{} encoder.Init(value) return encoder.Encode(value) } -func (value *PrefixInjection) Bytes() []byte { +func (value *PrefixInjectionInnerContent) Bytes() []byte { return value.Encode().Join() } -func ParsePrefixInjection(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { - context := PrefixInjectionParsingContext{} +func ParsePrefixInjectionInnerContent(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { + context := PrefixInjectionInnerContentParsingContext{} context.Init() return context.Parse(reader, ignoreCritical) } From ca0299e9e8474765ac676ae171fb37f8cd56a51f Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 11:08:50 -0700 Subject: [PATCH 06/31] fix command name to not use keyword component --- dv/dv/router.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dv/dv/router.go b/dv/dv/router.go index 785508d0..816dc8e9 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -273,8 +273,8 @@ func (dv *Router) register() (err error) { return err } - injectPrefix := enc.NewKeywordComponent("routing"). - Append(enc.NewKeywordComponent("inject")) + injectPrefix := enc.NewGenericComponent("routing"). + Append(enc.NewGenericComponent("inject")) if dv.enablePrefixInjection { err = dv.engine.AttachHandler(injectPrefix, From 59745488c06f5fad350e19b2c9b73e37a68aaede Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 11:34:44 -0700 Subject: [PATCH 07/31] remember to reply to prefix injection --- dv/dv/injection.go | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 51a4de0a..7936324a 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -8,10 +8,37 @@ import ( "github.com/named-data/ndnd/std/ndn" mgmt "github.com/named-data/ndnd/std/ndn/mgmt_2022" spec "github.com/named-data/ndnd/std/ndn/spec_2022" + sig "github.com/named-data/ndnd/std/security/signer" "github.com/named-data/ndnd/std/types/optional" + "time" ) func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { + res := &mgmt.ControlResponse{ + Val: &mgmt.ControlResponseVal{ + StatusCode: 400, + StatusText: "Failed to execute prefix injection", + Params: nil, + }, + } + + defer func() { + signer := sig.NewSha256Signer() + data, err := dv.engine.Spec().MakeData( + args.Interest.Name(), + &ndn.DataConfig{ + ContentType: optional.Some(ndn.ContentTypeBlob), + Freshness: optional.Some(1 * time.Second), + }, + res.Encode(), + signer) + if err != nil { + log.Warn(dv, "Failed to make inject response Data", "err", err) + return + } + args.Reply(data.Wire) + }() + // If there is no incoming face ID, we can't use this if !args.IncomingFaceId.IsSet() { log.Warn(dv, "Received Prefix Injection with no incoming face ID, ignoring") @@ -85,12 +112,12 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } - dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap()) + dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap(), res) }, }) } -func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) { +func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *mgmt.ControlResponse) { if contentType, set := object.ContentType().Get(); !set || contentType != ndn.ContentTypePrefixInjection { log.Warn(dv, "Prefix Injection Object does not have the correct content type", "contentType", object.ContentType()) @@ -157,4 +184,13 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) { if dirty { go dv.postUpdateRib() } + + res.Val.StatusCode = 200 + res.Val.StatusText = "Prefix Injection command successful" + res.Val.Params = &mgmt.ControlArgs{ + Name: prefix, + FaceId: optional.Some(faceId), + Origin: optional.Some(config.PrefixInjOrigin), + Cost: optional.Some(cost), + } } From 7b3e6fc610bd09f53f20f88bdfa14701582eec70 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 12:34:27 -0700 Subject: [PATCH 08/31] fix usage of wrong api for prefix table --- dv/dv/injection.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 7936324a..04f36066 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -180,10 +180,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m dv.mutex.Lock() defer dv.mutex.Unlock() - dirty := dv.rib.Set(prefix, dv.config.RouterName(), cost) - if dirty { - go dv.postUpdateRib() - } + dv.pfx.Announce(prefix, faceId, cost) res.Val.StatusCode = 200 res.Val.StatusText = "Prefix Injection command successful" From ecb70b053000df85d85dc51c4fb94e7a46ef25c0 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 16:03:58 -0700 Subject: [PATCH 09/31] fix trust anchor typo --- dv/dv/router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dv/dv/router.go b/dv/dv/router.go index 816dc8e9..1a3032cd 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -121,7 +121,7 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { if err != nil { return nil, err } - anchors := config.TrustAnchorNames() + anchors := config.PrefixInjectionTrustAnchorNames() prefixInjectionTrust, err = sec.NewTrustConfig(kc, schema, anchors) if err != nil { return nil, err From 6c1dc200230da2044d66eaf5a5a6c96eac716a2b Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 17:26:46 -0700 Subject: [PATCH 10/31] stapled certs are non-critical --- std/ndn/mgmt_2022/definitions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/ndn/mgmt_2022/definitions.go b/std/ndn/mgmt_2022/definitions.go index b39f4b48..bee6b619 100644 --- a/std/ndn/mgmt_2022/definitions.go +++ b/std/ndn/mgmt_2022/definitions.go @@ -341,7 +341,7 @@ type CsQuery struct { type PrefixInjection struct { //+field:sequence:enc.Wire:wire - StapledCertificates []enc.Wire `tlv:"0x2d"` + StapledCertificates []enc.Wire `tlv:"0x2e"` //+field:wire ObjectWire enc.Wire `tlv:"0x06"` } From d9e04f9c11810cfb7143312f3527622ad179da3f Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 17:34:13 -0700 Subject: [PATCH 11/31] regenerate --- std/ndn/mgmt_2022/zz_generated.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/ndn/mgmt_2022/zz_generated.go b/std/ndn/mgmt_2022/zz_generated.go index e0b6f2bb..15a74d75 100644 --- a/std/ndn/mgmt_2022/zz_generated.go +++ b/std/ndn/mgmt_2022/zz_generated.go @@ -6561,7 +6561,7 @@ func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf [] encoder := pseudoEncoder value := &pseudoValue if value.StapledCertificates != nil { - buf[pos] = byte(45) + buf[pos] = byte(46) pos += 1 pos += uint(enc.TLNum(encoder.StapledCertificates_length).EncodeInto(buf[pos:])) for _, w := range value.StapledCertificates { @@ -6625,7 +6625,7 @@ func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreC err = nil if handled := false; true { switch typ { - case 45: + case 46: if true { handled = true handled_StapledCertificates = true From f343014e1acb73d9d3cb21fb93d9d18d8d0aa72d Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 17:40:27 -0700 Subject: [PATCH 12/31] change parse order --- dv/dv/injection.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 04f36066..5b0fcbb8 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -51,15 +51,14 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } - // Decode Prefix Injection Object - // note: ReadData() will skip over any non-critical TLV arguments (StapledCertificate) - data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(args.Interest.AppParam())) + paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) return } - paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) + // Decode Prefix Injection Object + data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(paParams.ObjectWire)) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) return From 1fbc4503bbc9786161729cfcf4a55502a2d0c370 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 17:43:20 -0700 Subject: [PATCH 13/31] revert --- dv/dv/injection.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 5b0fcbb8..04f36066 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -51,14 +51,15 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } - paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) + // Decode Prefix Injection Object + // note: ReadData() will skip over any non-critical TLV arguments (StapledCertificate) + data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(args.Interest.AppParam())) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) return } - // Decode Prefix Injection Object - data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(paParams.ObjectWire)) + paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) return From 5164c881b0d09348754fbbc41f1dfe7b3d9f72fe Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 18:07:51 -0700 Subject: [PATCH 14/31] defer doesn't work with callbacks --- dv/dv/injection.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 04f36066..d046617e 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -22,7 +22,7 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { }, } - defer func() { + reply := func() { signer := sig.NewSha256Signer() data, err := dv.engine.Spec().MakeData( args.Interest.Name(), @@ -37,17 +37,19 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } args.Reply(data.Wire) - }() + } // If there is no incoming face ID, we can't use this if !args.IncomingFaceId.IsSet() { log.Warn(dv, "Received Prefix Injection with no incoming face ID, ignoring") + reply() return } // Check if app param is present if args.Interest.AppParam() == nil { log.Warn(dv, "Received Prefix Injection with no AppParam, ignoring") + reply() return } @@ -56,12 +58,14 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(args.Interest.AppParam())) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) + reply() return } paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) + reply() return } @@ -70,6 +74,7 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(certWire)) if err != nil { log.Warn(dv, "Stapled malformed certificate", "err", err) + reply() return } @@ -109,10 +114,12 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { Callback: func(valid bool, err error) { if !valid || err != nil { log.Warn(dv, "Failed to validate signature", "name", data.Name(), "valid", valid, "err", err) + reply() return } dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap(), res) + reply() }, }) } From c62b4af24898246112ce7266a71f5852b8a8c597 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 18:15:32 -0700 Subject: [PATCH 15/31] prefix injection remove --- dv/dv/injection.go | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index d046617e..90b7efeb 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -155,16 +155,18 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m return } + var shouldRemove bool var cost uint64 if params.ExpirationPeriod < 0 { log.Warn(dv, "Invalid ExpirationPeriod value", "ExpirationPeriod", params.ExpirationPeriod) return } else if params.ExpirationPeriod == 0 { // Remove the RIB entry - // TODO: do it the proper way + shouldRemove = true cost = config.CostInfinity } else { // Add or update RIB entry + shouldRemove = false cost = params.Cost.GetOr(0) if cost < 0 { log.Warn(dv, "Invalid Cost value", "Cost", cost) @@ -172,22 +174,38 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m } } - dv.nfdc.Exec(nfdc.NfdMgmtCmd{ - Module: "rib", - Cmd: "register", - Args: &mgmt.ControlArgs{ - Name: prefix, - FaceId: optional.Some(faceId), - Origin: optional.Some(config.PrefixInjOrigin), - Cost: optional.Some(cost), - }, - Retries: 3, - }) + if shouldRemove { + dv.nfdc.Exec(nfdc.NfdMgmtCmd{ + Module: "rib", + Cmd: "unregister", + Args: &mgmt.ControlArgs{ + Name: prefix, + FaceId: optional.Some(faceId), + }, + Retries: 3, + }) + } else { + dv.nfdc.Exec(nfdc.NfdMgmtCmd{ + Module: "rib", + Cmd: "register", + Args: &mgmt.ControlArgs{ + Name: prefix, + FaceId: optional.Some(faceId), + Origin: optional.Some(config.PrefixInjOrigin), + Cost: optional.Some(cost), + }, + Retries: 3, + }) + } dv.mutex.Lock() defer dv.mutex.Unlock() - dv.pfx.Announce(prefix, faceId, cost) + if shouldRemove { + dv.pfx.Withdraw(prefix, faceId) + } else { + dv.pfx.Announce(prefix, faceId, cost) + } res.Val.StatusCode = 200 res.Val.StatusText = "Prefix Injection command successful" From 40a36c6360cf0db7486b6df2e7927a94239e6154 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sat, 3 May 2025 21:13:41 -0700 Subject: [PATCH 16/31] avoid redundant parsing --- dv/dv/injection.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 90b7efeb..c98927cd 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -53,21 +53,23 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } - // Decode Prefix Injection Object - // note: ReadData() will skip over any non-critical TLV arguments (StapledCertificate) - data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(args.Interest.AppParam())) + paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) reply() return } - paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) + // Decode Prefix Injection Object + dCtx := spec.DataParsingContext{} + dCtx.Init() + data, err := dCtx.Parse(enc.NewWireView(paParams.ObjectWire), true) if err != nil { - log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) + log.Warn(dv, "Failed to parse Prefix Injection inner data", "err", err) reply() return } + sigCov := dCtx.SigCovered() var stapledCertCallbacks []ndn.ExpressCallbackArgs for _, certWire := range paParams.StapledCertificates { From 613c6b8427dbf936ea4170c6e1128b51e2397fba Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sun, 4 May 2025 11:04:28 -0700 Subject: [PATCH 17/31] change default behavior for backwards compatibility --- dv/config/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dv/config/config.go b/dv/config/config.go index 923308f8..6fdb38d9 100644 --- a/dv/config/config.go +++ b/dv/config/config.go @@ -90,8 +90,8 @@ func DefaultConfig() *Config { AdvertisementSyncInterval_ms: 5000, RouterDeadInterval_ms: 30000, KeyChainUri: "undefined", - PrefixInjectionSchemaPath: "insecure", - PrefixInjectionKeychainUri: "insecure", + PrefixInjectionSchemaPath: "deny", + PrefixInjectionKeychainUri: "undefined", } } From 417fb6c04395b1aade83d265e419d96dfd341fe4 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sun, 4 May 2025 11:25:10 -0700 Subject: [PATCH 18/31] remove negative cases for uint --- dv/dv/injection.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index c98927cd..e57544ab 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -159,10 +159,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m var shouldRemove bool var cost uint64 - if params.ExpirationPeriod < 0 { - log.Warn(dv, "Invalid ExpirationPeriod value", "ExpirationPeriod", params.ExpirationPeriod) - return - } else if params.ExpirationPeriod == 0 { + if params.ExpirationPeriod == 0 { // Remove the RIB entry shouldRemove = true cost = config.CostInfinity @@ -170,7 +167,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m // Add or update RIB entry shouldRemove = false cost = params.Cost.GetOr(0) - if cost < 0 { + if cost > config.CostInfinity { log.Warn(dv, "Invalid Cost value", "Cost", cost) return } From 36ff0ece3025f5eaa44ccda047fbb0a0c06d5441 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sun, 4 May 2025 11:30:55 -0700 Subject: [PATCH 19/31] fix import order for lint --- dv/dv/injection.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index e57544ab..d3468e76 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -1,6 +1,8 @@ package dv import ( + "time" + "github.com/named-data/ndnd/dv/config" "github.com/named-data/ndnd/dv/nfdc" enc "github.com/named-data/ndnd/std/encoding" @@ -10,7 +12,6 @@ import ( spec "github.com/named-data/ndnd/std/ndn/spec_2022" sig "github.com/named-data/ndnd/std/security/signer" "github.com/named-data/ndnd/std/types/optional" - "time" ) func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { From 541d50c4ddb065adbf3af5b7e34250aae7032e3b Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sun, 4 May 2025 16:27:12 -0700 Subject: [PATCH 20/31] refactor control command response, use binary fields, move defs to dv --- dv/dv/injection.go | 67 +++-- dv/tlv/definitions.go | 22 +- dv/tlv/zz_generated.go | 427 ++++++++++++++++++++++++++++ std/ndn/mgmt_2022/definitions.go | 17 -- std/ndn/mgmt_2022/zz_generated.go | 444 ------------------------------ 5 files changed, 488 insertions(+), 489 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index d3468e76..b44e7bfb 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -5,6 +5,7 @@ import ( "github.com/named-data/ndnd/dv/config" "github.com/named-data/ndnd/dv/nfdc" + "github.com/named-data/ndnd/dv/tlv" enc "github.com/named-data/ndnd/std/encoding" "github.com/named-data/ndnd/std/log" "github.com/named-data/ndnd/std/ndn" @@ -15,7 +16,7 @@ import ( ) func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { - res := &mgmt.ControlResponse{ + resError := &mgmt.ControlResponse{ Val: &mgmt.ControlResponseVal{ StatusCode: 400, StatusText: "Failed to execute prefix injection", @@ -23,7 +24,7 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { }, } - reply := func() { + reply := func(res *mgmt.ControlResponse) { signer := sig.NewSha256Signer() data, err := dv.engine.Spec().MakeData( args.Interest.Name(), @@ -43,41 +44,41 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { // If there is no incoming face ID, we can't use this if !args.IncomingFaceId.IsSet() { log.Warn(dv, "Received Prefix Injection with no incoming face ID, ignoring") - reply() + reply(resError) return } // Check if app param is present if args.Interest.AppParam() == nil { log.Warn(dv, "Received Prefix Injection with no AppParam, ignoring") - reply() + reply(resError) return } - paParams, err := mgmt.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) + paParams, err := tlv.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) - reply() + reply(resError) return } // Decode Prefix Injection Object dCtx := spec.DataParsingContext{} dCtx.Init() - data, err := dCtx.Parse(enc.NewWireView(paParams.ObjectWire), true) + data, err := dCtx.Parse(enc.NewBufferView(paParams.ObjectWire), true) if err != nil { log.Warn(dv, "Failed to parse Prefix Injection inner data", "err", err) - reply() + reply(resError) return } sigCov := dCtx.SigCovered() var stapledCertCallbacks []ndn.ExpressCallbackArgs for _, certWire := range paParams.StapledCertificates { - data, sigCov, err := spec.Spec{}.ReadData(enc.NewWireView(certWire)) + data, sigCov, err := spec.Spec{}.ReadData(enc.NewBufferView(certWire)) if err != nil { log.Warn(dv, "Stapled malformed certificate", "err", err) - reply() + reply(resError) return } @@ -85,7 +86,7 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { ndn.ExpressCallbackArgs{ Result: ndn.InterestResultData, Data: data, - RawData: certWire, + RawData: enc.Wire{certWire}, SigCovered: sigCov, IsLocal: true, }) @@ -117,21 +118,29 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { Callback: func(valid bool, err error) { if !valid || err != nil { log.Warn(dv, "Failed to validate signature", "name", data.Name(), "valid", valid, "err", err) - reply() + reply(resError) return } - dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap(), res) - reply() + res := dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap()) + reply(res) }, }) } -func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *mgmt.ControlResponse) { +func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt.ControlResponse { + resError := &mgmt.ControlResponse{ + Val: &mgmt.ControlResponseVal{ + StatusCode: 400, + StatusText: "Failed to execute prefix injection", + Params: nil, + }, + } + if contentType, set := object.ContentType().Get(); !set || contentType != ndn.ContentTypePrefixInjection { log.Warn(dv, "Prefix Injection Object does not have the correct content type", "contentType", object.ContentType()) - return + return resError } // TODO: reject already seen injections (using version) @@ -148,14 +157,14 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m if !found { log.Warn(dv, "Prefix Injection Object name not in correct format", "name", object.Name()) - return + return resError } piWire := object.Content() - params, err := mgmt.ParsePrefixInjectionInnerContent(enc.NewWireView(piWire), true) + params, err := tlv.ParsePrefixInjectionInnerContent(enc.NewWireView(piWire), true) if err != nil { log.Warn(dv, "Failed to parse prefix injection object", "err", err) - return + return resError } var shouldRemove bool @@ -170,7 +179,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m cost = params.Cost.GetOr(0) if cost > config.CostInfinity { log.Warn(dv, "Invalid Cost value", "Cost", cost) - return + return resError } } @@ -207,12 +216,16 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64, res *m dv.pfx.Announce(prefix, faceId, cost) } - res.Val.StatusCode = 200 - res.Val.StatusText = "Prefix Injection command successful" - res.Val.Params = &mgmt.ControlArgs{ - Name: prefix, - FaceId: optional.Some(faceId), - Origin: optional.Some(config.PrefixInjOrigin), - Cost: optional.Some(cost), + return &mgmt.ControlResponse{ + Val: &mgmt.ControlResponseVal{ + StatusCode: 200, + StatusText: "Prefix Injection command successful", + Params: &mgmt.ControlArgs{ + Name: prefix, + FaceId: optional.Some(faceId), + Origin: optional.Some(config.PrefixInjOrigin), + Cost: optional.Some(cost), + }, + }, } } diff --git a/dv/tlv/definitions.go b/dv/tlv/definitions.go index a05e71be..0fbc3058 100644 --- a/dv/tlv/definitions.go +++ b/dv/tlv/definitions.go @@ -1,7 +1,11 @@ //go:generate gondn_tlv_gen package tlv -import enc "github.com/named-data/ndnd/std/encoding" +import ( + enc "github.com/named-data/ndnd/std/encoding" + "github.com/named-data/ndnd/std/ndn/spec_2022" + "github.com/named-data/ndnd/std/types/optional" +) type Packet struct { //+field:struct:Advertisement @@ -68,3 +72,19 @@ type Status struct { //+field:natural NFibEntries uint64 `tlv:"0x19B"` } + +type PrefixInjection struct { + //+field:sequence:[]byte:binary:[]byte + StapledCertificates [][]byte `tlv:"0x2e"` + //+field:binary + ObjectWire []byte `tlv:"0x06"` +} + +type PrefixInjectionInnerContent struct { + //+field:natural + ExpirationPeriod uint64 `tlv:"0x6d"` + //+field:struct:spec_2022.ValidityPeriod + ValidityPeriod *spec_2022.ValidityPeriod `tlv:"0xfd"` + //+field:natural:optional + Cost optional.Optional[uint64] `tlv:"0x6a"` +} diff --git a/dv/tlv/zz_generated.go b/dv/tlv/zz_generated.go index b861309f..04eb1e29 100644 --- a/dv/tlv/zz_generated.go +++ b/dv/tlv/zz_generated.go @@ -7,6 +7,7 @@ import ( "strings" enc "github.com/named-data/ndnd/std/encoding" + "github.com/named-data/ndnd/std/ndn/spec_2022" ) type PacketEncoder struct { @@ -1683,3 +1684,429 @@ func ParseStatus(reader enc.WireView, ignoreCritical bool) (*Status, error) { context.Init() return context.Parse(reader, ignoreCritical) } + +type PrefixInjectionEncoder struct { + Length uint + + StapledCertificates_subencoder []struct { + } +} + +type PrefixInjectionParsingContext struct { +} + +func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { + { + StapledCertificates_l := len(value.StapledCertificates) + encoder.StapledCertificates_subencoder = make([]struct { + }, StapledCertificates_l) + for i := 0; i < StapledCertificates_l; i++ { + pseudoEncoder := &encoder.StapledCertificates_subencoder[i] + pseudoValue := struct { + StapledCertificates []byte + }{ + StapledCertificates: value.StapledCertificates[i], + } + { + encoder := pseudoEncoder + value := &pseudoValue + + _ = encoder + _ = value + } + } + } + + l := uint(0) + if value.StapledCertificates != nil { + for seq_i, seq_v := range value.StapledCertificates { + pseudoEncoder := &encoder.StapledCertificates_subencoder[seq_i] + pseudoValue := struct { + StapledCertificates []byte + }{ + StapledCertificates: seq_v, + } + { + encoder := pseudoEncoder + value := &pseudoValue + if value.StapledCertificates != nil { + l += 1 + l += uint(enc.TLNum(len(value.StapledCertificates)).EncodingLength()) + l += uint(len(value.StapledCertificates)) + } + _ = encoder + _ = value + } + } + } + if value.ObjectWire != nil { + l += 1 + l += uint(enc.TLNum(len(value.ObjectWire)).EncodingLength()) + l += uint(len(value.ObjectWire)) + } + encoder.Length = l + +} + +func (context *PrefixInjectionParsingContext) Init() { + +} + +func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf []byte) { + + pos := uint(0) + + if value.StapledCertificates != nil { + for seq_i, seq_v := range value.StapledCertificates { + pseudoEncoder := &encoder.StapledCertificates_subencoder[seq_i] + pseudoValue := struct { + StapledCertificates []byte + }{ + StapledCertificates: seq_v, + } + { + encoder := pseudoEncoder + value := &pseudoValue + if value.StapledCertificates != nil { + buf[pos] = byte(46) + pos += 1 + pos += uint(enc.TLNum(len(value.StapledCertificates)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.StapledCertificates) + pos += uint(len(value.StapledCertificates)) + } + _ = encoder + _ = value + } + } + } + if value.ObjectWire != nil { + buf[pos] = byte(6) + pos += 1 + pos += uint(enc.TLNum(len(value.ObjectWire)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.ObjectWire) + pos += uint(len(value.ObjectWire)) + } +} + +func (encoder *PrefixInjectionEncoder) Encode(value *PrefixInjection) enc.Wire { + + wire := make(enc.Wire, 1) + wire[0] = make([]byte, encoder.Length) + buf := wire[0] + encoder.EncodeInto(value, buf) + + return wire +} + +func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { + + var handled_StapledCertificates bool = false + var handled_ObjectWire bool = false + + progress := -1 + _ = progress + + value := &PrefixInjection{} + var err error + var startPos int + for { + startPos = reader.Pos() + if startPos >= reader.Length() { + break + } + typ := enc.TLNum(0) + l := enc.TLNum(0) + typ, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + l, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + + err = nil + if handled := false; true { + switch typ { + case 46: + if true { + handled = true + handled_StapledCertificates = true + if value.StapledCertificates == nil { + value.StapledCertificates = make([][]byte, 0) + } + { + pseudoValue := struct { + StapledCertificates []byte + }{} + { + value := &pseudoValue + value.StapledCertificates = make([]byte, l) + _, err = reader.ReadFull(value.StapledCertificates) + _ = value + } + value.StapledCertificates = append(value.StapledCertificates, pseudoValue.StapledCertificates) + } + progress-- + } + case 6: + if true { + handled = true + handled_ObjectWire = true + value.ObjectWire = make([]byte, l) + _, err = reader.ReadFull(value.ObjectWire) + } + default: + if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { + return nil, enc.ErrUnrecognizedField{TypeNum: typ} + } + handled = true + err = reader.Skip(int(l)) + } + if err == nil && !handled { + } + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} + } + } + } + + startPos = reader.Pos() + err = nil + + if !handled_StapledCertificates && err == nil { + // sequence - skip + } + if !handled_ObjectWire && err == nil { + value.ObjectWire = nil + } + + if err != nil { + return nil, err + } + + return value, nil +} + +func (value *PrefixInjection) Encode() enc.Wire { + encoder := PrefixInjectionEncoder{} + encoder.Init(value) + return encoder.Encode(value) +} + +func (value *PrefixInjection) Bytes() []byte { + return value.Encode().Join() +} + +func ParsePrefixInjection(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { + context := PrefixInjectionParsingContext{} + context.Init() + return context.Parse(reader, ignoreCritical) +} + +type PrefixInjectionInnerContentEncoder struct { + Length uint + + ValidityPeriod_encoder spec_2022.ValidityPeriodEncoder +} + +type PrefixInjectionInnerContentParsingContext struct { + ValidityPeriod_context spec_2022.ValidityPeriodParsingContext +} + +func (encoder *PrefixInjectionInnerContentEncoder) Init(value *PrefixInjectionInnerContent) { + + if value.ValidityPeriod != nil { + encoder.ValidityPeriod_encoder.Init(value.ValidityPeriod) + } + + l := uint(0) + l += 1 + l += uint(1 + enc.Nat(value.ExpirationPeriod).EncodingLength()) + if value.ValidityPeriod != nil { + l += 3 + l += uint(enc.TLNum(encoder.ValidityPeriod_encoder.Length).EncodingLength()) + l += encoder.ValidityPeriod_encoder.Length + } + if optval, ok := value.Cost.Get(); ok { + l += 1 + l += uint(1 + enc.Nat(optval).EncodingLength()) + } + encoder.Length = l + +} + +func (context *PrefixInjectionInnerContentParsingContext) Init() { + + context.ValidityPeriod_context.Init() + +} + +func (encoder *PrefixInjectionInnerContentEncoder) EncodeInto(value *PrefixInjectionInnerContent, buf []byte) { + + pos := uint(0) + + buf[pos] = byte(109) + pos += 1 + + buf[pos] = byte(enc.Nat(value.ExpirationPeriod).EncodeInto(buf[pos+1:])) + pos += uint(1 + buf[pos]) + if value.ValidityPeriod != nil { + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(253)) + pos += 3 + pos += uint(enc.TLNum(encoder.ValidityPeriod_encoder.Length).EncodeInto(buf[pos:])) + if encoder.ValidityPeriod_encoder.Length > 0 { + encoder.ValidityPeriod_encoder.EncodeInto(value.ValidityPeriod, buf[pos:]) + pos += encoder.ValidityPeriod_encoder.Length + } + } + if optval, ok := value.Cost.Get(); ok { + buf[pos] = byte(106) + pos += 1 + + buf[pos] = byte(enc.Nat(optval).EncodeInto(buf[pos+1:])) + pos += uint(1 + buf[pos]) + + } +} + +func (encoder *PrefixInjectionInnerContentEncoder) Encode(value *PrefixInjectionInnerContent) enc.Wire { + + wire := make(enc.Wire, 1) + wire[0] = make([]byte, encoder.Length) + buf := wire[0] + encoder.EncodeInto(value, buf) + + return wire +} + +func (context *PrefixInjectionInnerContentParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { + + var handled_ExpirationPeriod bool = false + var handled_ValidityPeriod bool = false + var handled_Cost bool = false + + progress := -1 + _ = progress + + value := &PrefixInjectionInnerContent{} + var err error + var startPos int + for { + startPos = reader.Pos() + if startPos >= reader.Length() { + break + } + typ := enc.TLNum(0) + l := enc.TLNum(0) + typ, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + l, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + + err = nil + if handled := false; true { + switch typ { + case 109: + if true { + handled = true + handled_ExpirationPeriod = true + value.ExpirationPeriod = uint64(0) + { + for i := 0; i < int(l); i++ { + x := byte(0) + x, err = reader.ReadByte() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + break + } + value.ExpirationPeriod = uint64(value.ExpirationPeriod<<8) | uint64(x) + } + } + } + case 253: + if true { + handled = true + handled_ValidityPeriod = true + value.ValidityPeriod, err = context.ValidityPeriod_context.Parse(reader.Delegate(int(l)), ignoreCritical) + } + case 106: + if true { + handled = true + handled_Cost = true + { + optval := uint64(0) + optval = uint64(0) + { + for i := 0; i < int(l); i++ { + x := byte(0) + x, err = reader.ReadByte() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + break + } + optval = uint64(optval<<8) | uint64(x) + } + } + value.Cost.Set(optval) + } + } + default: + if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { + return nil, enc.ErrUnrecognizedField{TypeNum: typ} + } + handled = true + err = reader.Skip(int(l)) + } + if err == nil && !handled { + } + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} + } + } + } + + startPos = reader.Pos() + err = nil + + if !handled_ExpirationPeriod && err == nil { + err = enc.ErrSkipRequired{Name: "ExpirationPeriod", TypeNum: 109} + } + if !handled_ValidityPeriod && err == nil { + value.ValidityPeriod = nil + } + if !handled_Cost && err == nil { + value.Cost.Unset() + } + + if err != nil { + return nil, err + } + + return value, nil +} + +func (value *PrefixInjectionInnerContent) Encode() enc.Wire { + encoder := PrefixInjectionInnerContentEncoder{} + encoder.Init(value) + return encoder.Encode(value) +} + +func (value *PrefixInjectionInnerContent) Bytes() []byte { + return value.Encode().Join() +} + +func ParsePrefixInjectionInnerContent(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { + context := PrefixInjectionInnerContentParsingContext{} + context.Init() + return context.Parse(reader, ignoreCritical) +} diff --git a/std/ndn/mgmt_2022/definitions.go b/std/ndn/mgmt_2022/definitions.go index bee6b619..c438b7b4 100644 --- a/std/ndn/mgmt_2022/definitions.go +++ b/std/ndn/mgmt_2022/definitions.go @@ -5,7 +5,6 @@ import ( "time" enc "github.com/named-data/ndnd/std/encoding" - "github.com/named-data/ndnd/std/ndn/spec_2022" "github.com/named-data/ndnd/std/types/optional" ) @@ -338,19 +337,3 @@ type CsQuery struct { PacketSize uint64 FreshnessPeriod uint64 } - -type PrefixInjection struct { - //+field:sequence:enc.Wire:wire - StapledCertificates []enc.Wire `tlv:"0x2e"` - //+field:wire - ObjectWire enc.Wire `tlv:"0x06"` -} - -type PrefixInjectionInnerContent struct { - //+field:natural - ExpirationPeriod uint64 `tlv:"0x6d"` - //+field:struct:spec_2022.ValidityPeriod - ValidityPeriod *spec_2022.ValidityPeriod `tlv:"0xfd"` - //+field:natural:optional - Cost optional.Optional[uint64] `tlv:"0x6a"` -} diff --git a/std/ndn/mgmt_2022/zz_generated.go b/std/ndn/mgmt_2022/zz_generated.go index 15a74d75..f970a346 100644 --- a/std/ndn/mgmt_2022/zz_generated.go +++ b/std/ndn/mgmt_2022/zz_generated.go @@ -2,14 +2,12 @@ package mgmt_2022 import ( - "encoding/binary" "io" "strings" "time" enc "github.com/named-data/ndnd/std/encoding" - "github.com/named-data/ndnd/std/ndn/spec_2022" ) type StrategyEncoder struct { @@ -6463,445 +6461,3 @@ func ParseCsInfoMsg(reader enc.WireView, ignoreCritical bool) (*CsInfoMsg, error context.Init() return context.Parse(reader, ignoreCritical) } - -type PrefixInjectionEncoder struct { - Length uint - - StapledCertificates_subencoder []struct { - StapledCertificates_length uint - } - ObjectWire_length uint -} - -type PrefixInjectionParsingContext struct { -} - -func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { - { - StapledCertificates_l := len(value.StapledCertificates) - encoder.StapledCertificates_subencoder = make([]struct { - StapledCertificates_length uint - }, StapledCertificates_l) - for i := 0; i < StapledCertificates_l; i++ { - pseudoEncoder := &encoder.StapledCertificates_subencoder[i] - pseudoValue := struct { - StapledCertificates enc.Wire - }{ - StapledCertificates: value.StapledCertificates[i], - } - { - encoder := pseudoEncoder - value := &pseudoValue - if value.StapledCertificates != nil { - encoder.StapledCertificates_length = 0 - for _, c := range value.StapledCertificates { - encoder.StapledCertificates_length += uint(len(c)) - } - } - _ = encoder - _ = value - } - } - } - if value.ObjectWire != nil { - encoder.ObjectWire_length = 0 - for _, c := range value.ObjectWire { - encoder.ObjectWire_length += uint(len(c)) - } - } - - l := uint(0) - if value.StapledCertificates != nil { - for seq_i, seq_v := range value.StapledCertificates { - pseudoEncoder := &encoder.StapledCertificates_subencoder[seq_i] - pseudoValue := struct { - StapledCertificates enc.Wire - }{ - StapledCertificates: seq_v, - } - { - encoder := pseudoEncoder - value := &pseudoValue - if value.StapledCertificates != nil { - l += 1 - l += uint(enc.TLNum(encoder.StapledCertificates_length).EncodingLength()) - l += encoder.StapledCertificates_length - } - _ = encoder - _ = value - } - } - } - if value.ObjectWire != nil { - l += 1 - l += uint(enc.TLNum(encoder.ObjectWire_length).EncodingLength()) - l += encoder.ObjectWire_length - } - encoder.Length = l - -} - -func (context *PrefixInjectionParsingContext) Init() { - -} - -func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf []byte) { - - pos := uint(0) - - if value.StapledCertificates != nil { - for seq_i, seq_v := range value.StapledCertificates { - pseudoEncoder := &encoder.StapledCertificates_subencoder[seq_i] - pseudoValue := struct { - StapledCertificates enc.Wire - }{ - StapledCertificates: seq_v, - } - { - encoder := pseudoEncoder - value := &pseudoValue - if value.StapledCertificates != nil { - buf[pos] = byte(46) - pos += 1 - pos += uint(enc.TLNum(encoder.StapledCertificates_length).EncodeInto(buf[pos:])) - for _, w := range value.StapledCertificates { - copy(buf[pos:], w) - pos += uint(len(w)) - } - } - _ = encoder - _ = value - } - } - } - if value.ObjectWire != nil { - buf[pos] = byte(6) - pos += 1 - pos += uint(enc.TLNum(encoder.ObjectWire_length).EncodeInto(buf[pos:])) - for _, w := range value.ObjectWire { - copy(buf[pos:], w) - pos += uint(len(w)) - } - } -} - -func (encoder *PrefixInjectionEncoder) Encode(value *PrefixInjection) enc.Wire { - - wire := make(enc.Wire, 1) - wire[0] = make([]byte, encoder.Length) - buf := wire[0] - encoder.EncodeInto(value, buf) - - return wire -} - -func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { - - var handled_StapledCertificates bool = false - var handled_ObjectWire bool = false - - progress := -1 - _ = progress - - value := &PrefixInjection{} - var err error - var startPos int - for { - startPos = reader.Pos() - if startPos >= reader.Length() { - break - } - typ := enc.TLNum(0) - l := enc.TLNum(0) - typ, err = reader.ReadTLNum() - if err != nil { - return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} - } - l, err = reader.ReadTLNum() - if err != nil { - return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} - } - - err = nil - if handled := false; true { - switch typ { - case 46: - if true { - handled = true - handled_StapledCertificates = true - if value.StapledCertificates == nil { - value.StapledCertificates = make([]enc.Wire, 0) - } - { - pseudoValue := struct { - StapledCertificates enc.Wire - }{} - { - value := &pseudoValue - value.StapledCertificates, err = reader.ReadWire(int(l)) - _ = value - } - value.StapledCertificates = append(value.StapledCertificates, pseudoValue.StapledCertificates) - } - progress-- - } - case 6: - if true { - handled = true - handled_ObjectWire = true - value.ObjectWire, err = reader.ReadWire(int(l)) - } - default: - if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { - return nil, enc.ErrUnrecognizedField{TypeNum: typ} - } - handled = true - err = reader.Skip(int(l)) - } - if err == nil && !handled { - } - if err != nil { - return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} - } - } - } - - startPos = reader.Pos() - err = nil - - if !handled_StapledCertificates && err == nil { - // sequence - skip - } - if !handled_ObjectWire && err == nil { - value.ObjectWire = nil - } - - if err != nil { - return nil, err - } - - return value, nil -} - -func (value *PrefixInjection) Encode() enc.Wire { - encoder := PrefixInjectionEncoder{} - encoder.Init(value) - return encoder.Encode(value) -} - -func (value *PrefixInjection) Bytes() []byte { - return value.Encode().Join() -} - -func ParsePrefixInjection(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { - context := PrefixInjectionParsingContext{} - context.Init() - return context.Parse(reader, ignoreCritical) -} - -type PrefixInjectionInnerContentEncoder struct { - Length uint - - ValidityPeriod_encoder spec_2022.ValidityPeriodEncoder -} - -type PrefixInjectionInnerContentParsingContext struct { - ValidityPeriod_context spec_2022.ValidityPeriodParsingContext -} - -func (encoder *PrefixInjectionInnerContentEncoder) Init(value *PrefixInjectionInnerContent) { - - if value.ValidityPeriod != nil { - encoder.ValidityPeriod_encoder.Init(value.ValidityPeriod) - } - - l := uint(0) - l += 1 - l += uint(1 + enc.Nat(value.ExpirationPeriod).EncodingLength()) - if value.ValidityPeriod != nil { - l += 3 - l += uint(enc.TLNum(encoder.ValidityPeriod_encoder.Length).EncodingLength()) - l += encoder.ValidityPeriod_encoder.Length - } - if optval, ok := value.Cost.Get(); ok { - l += 1 - l += uint(1 + enc.Nat(optval).EncodingLength()) - } - encoder.Length = l - -} - -func (context *PrefixInjectionInnerContentParsingContext) Init() { - - context.ValidityPeriod_context.Init() - -} - -func (encoder *PrefixInjectionInnerContentEncoder) EncodeInto(value *PrefixInjectionInnerContent, buf []byte) { - - pos := uint(0) - - buf[pos] = byte(109) - pos += 1 - - buf[pos] = byte(enc.Nat(value.ExpirationPeriod).EncodeInto(buf[pos+1:])) - pos += uint(1 + buf[pos]) - if value.ValidityPeriod != nil { - buf[pos] = 253 - binary.BigEndian.PutUint16(buf[pos+1:], uint16(253)) - pos += 3 - pos += uint(enc.TLNum(encoder.ValidityPeriod_encoder.Length).EncodeInto(buf[pos:])) - if encoder.ValidityPeriod_encoder.Length > 0 { - encoder.ValidityPeriod_encoder.EncodeInto(value.ValidityPeriod, buf[pos:]) - pos += encoder.ValidityPeriod_encoder.Length - } - } - if optval, ok := value.Cost.Get(); ok { - buf[pos] = byte(106) - pos += 1 - - buf[pos] = byte(enc.Nat(optval).EncodeInto(buf[pos+1:])) - pos += uint(1 + buf[pos]) - - } -} - -func (encoder *PrefixInjectionInnerContentEncoder) Encode(value *PrefixInjectionInnerContent) enc.Wire { - - wire := make(enc.Wire, 1) - wire[0] = make([]byte, encoder.Length) - buf := wire[0] - encoder.EncodeInto(value, buf) - - return wire -} - -func (context *PrefixInjectionInnerContentParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { - - var handled_ExpirationPeriod bool = false - var handled_ValidityPeriod bool = false - var handled_Cost bool = false - - progress := -1 - _ = progress - - value := &PrefixInjectionInnerContent{} - var err error - var startPos int - for { - startPos = reader.Pos() - if startPos >= reader.Length() { - break - } - typ := enc.TLNum(0) - l := enc.TLNum(0) - typ, err = reader.ReadTLNum() - if err != nil { - return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} - } - l, err = reader.ReadTLNum() - if err != nil { - return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} - } - - err = nil - if handled := false; true { - switch typ { - case 109: - if true { - handled = true - handled_ExpirationPeriod = true - value.ExpirationPeriod = uint64(0) - { - for i := 0; i < int(l); i++ { - x := byte(0) - x, err = reader.ReadByte() - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - break - } - value.ExpirationPeriod = uint64(value.ExpirationPeriod<<8) | uint64(x) - } - } - } - case 253: - if true { - handled = true - handled_ValidityPeriod = true - value.ValidityPeriod, err = context.ValidityPeriod_context.Parse(reader.Delegate(int(l)), ignoreCritical) - } - case 106: - if true { - handled = true - handled_Cost = true - { - optval := uint64(0) - optval = uint64(0) - { - for i := 0; i < int(l); i++ { - x := byte(0) - x, err = reader.ReadByte() - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - break - } - optval = uint64(optval<<8) | uint64(x) - } - } - value.Cost.Set(optval) - } - } - default: - if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { - return nil, enc.ErrUnrecognizedField{TypeNum: typ} - } - handled = true - err = reader.Skip(int(l)) - } - if err == nil && !handled { - } - if err != nil { - return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} - } - } - } - - startPos = reader.Pos() - err = nil - - if !handled_ExpirationPeriod && err == nil { - err = enc.ErrSkipRequired{Name: "ExpirationPeriod", TypeNum: 109} - } - if !handled_ValidityPeriod && err == nil { - value.ValidityPeriod = nil - } - if !handled_Cost && err == nil { - value.Cost.Unset() - } - - if err != nil { - return nil, err - } - - return value, nil -} - -func (value *PrefixInjectionInnerContent) Encode() enc.Wire { - encoder := PrefixInjectionInnerContentEncoder{} - encoder.Init(value) - return encoder.Encode(value) -} - -func (value *PrefixInjectionInnerContent) Bytes() []byte { - return value.Encode().Join() -} - -func ParsePrefixInjectionInnerContent(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { - context := PrefixInjectionInnerContentParsingContext{} - context.Init() - return context.Parse(reader, ignoreCritical) -} From 8240215764e650726ca4432afdf8f4f779b62782 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Fri, 16 May 2025 13:57:29 -0700 Subject: [PATCH 21/31] update constants and format to comply with new protocol format --- dv/dv/injection.go | 19 +++++++++++++------ dv/tlv/definitions.go | 2 +- std/ndn/constants.go | 1 - 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index b44e7bfb..ed652b38 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -62,7 +62,7 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } - // Decode Prefix Injection Object + // Decode Prefix Announcement Object dCtx := spec.DataParsingContext{} dCtx.Init() data, err := dCtx.Parse(enc.NewBufferView(paParams.ObjectWire), true) @@ -137,8 +137,8 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. }, } - if contentType, set := object.ContentType().Get(); !set || contentType != ndn.ContentTypePrefixInjection { - log.Warn(dv, "Prefix Injection Object does not have the correct content type", + if contentType, set := object.ContentType().Get(); !set || contentType != ndn.ContentTypePrefixAnnouncement { + log.Warn(dv, "Prefix Announcement Object does not have the correct content type", "contentType", object.ContentType()) return resError } @@ -148,7 +148,14 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. found := false for i, c := range object.Name() { - if c.IsKeyword("inject") { + if c.IsKeyword("PA") { + if len(object.Name()) != i+2 || + !object.Name().At(i+1).IsSegment() || + object.Name().At(i+1).NumberVal() != 0 { + found = false + break + } + prefix = object.Name().Prefix(i) found = true break @@ -156,14 +163,14 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. } if !found { - log.Warn(dv, "Prefix Injection Object name not in correct format", "name", object.Name()) + log.Warn(dv, "Prefix Announcement Object name not in correct format", "name", object.Name()) return resError } piWire := object.Content() params, err := tlv.ParsePrefixInjectionInnerContent(enc.NewWireView(piWire), true) if err != nil { - log.Warn(dv, "Failed to parse prefix injection object", "err", err) + log.Warn(dv, "Failed to parse prefix announcement object", "err", err) return resError } diff --git a/dv/tlv/definitions.go b/dv/tlv/definitions.go index 0fbc3058..b305a305 100644 --- a/dv/tlv/definitions.go +++ b/dv/tlv/definitions.go @@ -75,7 +75,7 @@ type Status struct { type PrefixInjection struct { //+field:sequence:[]byte:binary:[]byte - StapledCertificates [][]byte `tlv:"0x2e"` + StapledCertificates [][]byte `tlv:"0x216"` //+field:binary ObjectWire []byte `tlv:"0x06"` } diff --git a/std/ndn/constants.go b/std/ndn/constants.go index 7e484d16..0e72b66b 100644 --- a/std/ndn/constants.go +++ b/std/ndn/constants.go @@ -14,7 +14,6 @@ const ( ContentTypeManifest ContentType = 4 ContentTypePrefixAnnouncement ContentType = 5 ContentTypeEncapsulatedData ContentType = 6 - ContentTypePrefixInjection ContentType = 7 ContentTypeSigningKey ContentType = 9 ) From 811015f9e5deb5ac10fc393affcbc67bc71d84cf Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Fri, 16 May 2025 15:01:27 -0700 Subject: [PATCH 22/31] fix pa object name parsing --- dv/dv/injection.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index ed652b38..8f2b60c0 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -149,9 +149,10 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. for i, c := range object.Name() { if c.IsKeyword("PA") { - if len(object.Name()) != i+2 || - !object.Name().At(i+1).IsSegment() || - object.Name().At(i+1).NumberVal() != 0 { + if len(object.Name()) != i+3 || + !object.Name().At(i+1).IsVersion() || + !object.Name().At(i+2).IsSegment() || + object.Name().At(i+2).NumberVal() != 0 { found = false break } From 984aeffd4f14ffbb54177e9f7cc59b7e8db52476 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Fri, 16 May 2025 15:04:46 -0700 Subject: [PATCH 23/31] generate --- dv/tlv/zz_generated.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dv/tlv/zz_generated.go b/dv/tlv/zz_generated.go index 04eb1e29..22fce3a6 100644 --- a/dv/tlv/zz_generated.go +++ b/dv/tlv/zz_generated.go @@ -1730,7 +1730,7 @@ func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { encoder := pseudoEncoder value := &pseudoValue if value.StapledCertificates != nil { - l += 1 + l += 3 l += uint(enc.TLNum(len(value.StapledCertificates)).EncodingLength()) l += uint(len(value.StapledCertificates)) } @@ -1768,8 +1768,9 @@ func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf [] encoder := pseudoEncoder value := &pseudoValue if value.StapledCertificates != nil { - buf[pos] = byte(46) - pos += 1 + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(534)) + pos += 3 pos += uint(enc.TLNum(len(value.StapledCertificates)).EncodeInto(buf[pos:])) copy(buf[pos:], value.StapledCertificates) pos += uint(len(value.StapledCertificates)) @@ -1828,7 +1829,7 @@ func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreC err = nil if handled := false; true { switch typ { - case 46: + case 534: if true { handled = true handled_StapledCertificates = true From eaa1cd7295faaafff065e3e994405854c8588641 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sun, 18 May 2025 12:12:48 -0700 Subject: [PATCH 24/31] reject seen PA --- dv/dv/injection.go | 21 ++++++++++++++++++++- dv/dv/router.go | 4 ++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 8f2b60c0..7bd78568 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -143,9 +143,9 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. return resError } - // TODO: reject already seen injections (using version) var prefix enc.Name found := false + var version uint64 for i, c := range object.Name() { if c.IsKeyword("PA") { @@ -158,6 +158,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. } prefix = object.Name().Prefix(i) + version = object.Name().At(i + 1).NumberVal() found = true break } @@ -168,6 +169,24 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. return resError } + // Check if we've seen a newer version of this prefix injection + prefixHash := prefix.Hash() + if lastVersion, exists := dv.seenPrefixVersions[prefixHash]; exists && lastVersion >= version { + log.Info(dv, "Rejecting older or duplicate prefix injection", + "prefix", prefix, + "version", version, + "lastVersion", lastVersion) + return &mgmt.ControlResponse{ + Val: &mgmt.ControlResponseVal{ + StatusCode: 409, + StatusText: "Older or duplicate prefix injection version", + Params: nil, + }, + } + } + + dv.seenPrefixVersions[prefixHash] = version + piWire := object.Content() params, err := tlv.ParsePrefixInjectionInnerContent(enc.NewWireView(piWire), true) if err != nil { diff --git a/dv/dv/router.go b/dv/dv/router.go index 1a3032cd..259527aa 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -65,6 +65,9 @@ type Router struct { rib *table.Rib // forwarding table fib *table.Fib + + // map to track seen prefix injection versions (prefix hash -> version) + seenPrefixVersions map[uint64]uint64 } // Create a new DV router. @@ -138,6 +141,7 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { prefixInjectionClient: object.NewClient(engine, prefixInjectionStore, prefixInjectionTrust), nfdc: nfdc.NewNfdMgmtThread(engine), mutex: sync.Mutex{}, + seenPrefixVersions: make(map[uint64]uint64), } // Initialize advertisement module From 2aced71ea2d5554a4d5834bf1ca0683d6bb6f079 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Sun, 18 May 2025 12:46:43 -0700 Subject: [PATCH 25/31] check validityperiod --- dv/dv/injection.go | 48 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/dv/dv/injection.go b/dv/dv/injection.go index 7bd78568..9f7ed86f 100644 --- a/dv/dv/injection.go +++ b/dv/dv/injection.go @@ -194,9 +194,52 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. return resError } + // Check validity period if it exists + expirationPeriod := params.ExpirationPeriod + if params.ValidityPeriod != nil { + const timeFormat = "20060102T150405" // Format for YYYYMMDDThhmmss + notBefore, err := time.Parse(timeFormat, params.ValidityPeriod.NotBefore) + if err != nil { + log.Warn(dv, "Failed to parse NotBefore time", "err", err, "value", params.ValidityPeriod.NotBefore) + return resError + } + notAfter, err := time.Parse(timeFormat, params.ValidityPeriod.NotAfter) + if err != nil { + log.Warn(dv, "Failed to parse NotAfter time", "err", err, "value", params.ValidityPeriod.NotAfter) + return resError + } + + now := time.Now().UTC() + if now.Before(notBefore) || now.After(notAfter) { + log.Info(dv, "Prefix injection outside validity period", + "prefix", prefix, + "notBefore", notBefore, + "notAfter", notAfter, + "now", now) + return &mgmt.ControlResponse{ + Val: &mgmt.ControlResponseVal{ + StatusCode: 403, + StatusText: "Prefix injection outside validity period", + Params: nil, + }, + } + } + + // Adjust expiration to be the minimum of the current expiration and notAfter - now + if expirationPeriod > 0 { + timeUntilExpiry := notAfter.Sub(now) + if timeUntilExpiry < time.Duration(expirationPeriod)*time.Millisecond { + expirationPeriod = uint64(timeUntilExpiry.Milliseconds()) + log.Debug(dv, "Adjusted expiration period based on validity period", + "prefix", prefix, + "newExpiration", expirationPeriod) + } + } + } + var shouldRemove bool var cost uint64 - if params.ExpirationPeriod == 0 { + if expirationPeriod == 0 { // Remove the RIB entry shouldRemove = true cost = config.CostInfinity @@ -210,6 +253,9 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. } } + // TODO: use the expiration period to set the lifetime of the RIB and prefix table entry + // (Currently the prefix table does not have a lifetime) + if shouldRemove { dv.nfdc.Exec(nfdc.NfdMgmtCmd{ Module: "rib", From 2af277e325240f1f15599a0ecdf112699a9f064d Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Mon, 2 Jun 2025 10:34:14 -0700 Subject: [PATCH 26/31] rename injection to insertion --- dv/config/config.go | 32 ++++++++--------- dv/dv.sample.yml | 14 ++++---- dv/dv/{injection.go => insertion.go} | 48 ++++++++++++------------- dv/dv/router.go | 50 +++++++++++++------------- dv/tlv/definitions.go | 4 +-- dv/tlv/zz_generated.go | 52 ++++++++++++++-------------- std/ndn/mgmt_2022/route.go | 2 +- 7 files changed, 101 insertions(+), 101 deletions(-) rename dv/dv/{injection.go => insertion.go} (82%) diff --git a/dv/config/config.go b/dv/config/config.go index 6fdb38d9..3cae70a6 100644 --- a/dv/config/config.go +++ b/dv/config/config.go @@ -17,7 +17,7 @@ const CostPfxInfinity = uint64(0xFFFFFFFF) // NlsrOrigin is the origin to use for local registration. const NlsrOrigin = uint64(mgmt.RouteOriginNLSR) -const PrefixInjOrigin = uint64(mgmt.RouteOriginPrefixInj) +const PrefixInsOrigin = uint64(mgmt.RouteOriginPrefixIns) var MulticastStrategy = enc.LOCALHOST. Append(enc.NewGenericComponent("nfd")). @@ -40,12 +40,12 @@ type Config struct { KeyChainUri string `json:"keychain"` // List of trust anchor full names. TrustAnchors []string `json:"trust_anchors"` - // Path to trust schema for prefix injection. - PrefixInjectionSchemaPath string `json:"prefix_injection_schema"` - // URI specifying KeyChain location for prefix injection verifier. - PrefixInjectionKeychainUri string `json:"prefix_injection_keychain"` - // List of trust anchor full names for prefix injection. - PrefixInjectionTrustAnchors []string `json:"prefix_injection_trust_anchors"` + // Path to trust schema for prefix insertion. + PrefixInsertionSchemaPath string `json:"prefix_insertion_schema"` + // URI specifying KeyChain location for prefix insertion verifier. + PrefixInsertionKeychainUri string `json:"prefix_insertion_keychain"` + // List of trust anchor full names for prefix insertion. + PrefixInsertionTrustAnchors []string `json:"prefix_insertion_trust_anchors"` // List of permanent neighbors. Neighbors []Neighbor `json:"neighbors"` @@ -67,8 +67,8 @@ type Config struct { mgmtPrefix enc.Name // Trust anchor names trustAnchorsN []enc.Name - // Prefix Injection trust anchor names - prefixInjectionTrustAnchorsN []enc.Name + // Prefix Insertion trust anchor names + prefixInsertionTrustAnchorsN []enc.Name } type Neighbor struct { @@ -90,8 +90,8 @@ func DefaultConfig() *Config { AdvertisementSyncInterval_ms: 5000, RouterDeadInterval_ms: 30000, KeyChainUri: "undefined", - PrefixInjectionSchemaPath: "deny", - PrefixInjectionKeychainUri: "undefined", + PrefixInsertionSchemaPath: "deny", + PrefixInsertionKeychainUri: "undefined", } } @@ -147,13 +147,13 @@ func (c *Config) Parse() (err error) { c.trustAnchorsN = append(c.trustAnchorsN, name) } - c.prefixInjectionTrustAnchorsN = make([]enc.Name, 0, len(c.PrefixInjectionTrustAnchors)) - for _, anchor := range c.PrefixInjectionTrustAnchors { + c.prefixInsertionTrustAnchorsN = make([]enc.Name, 0, len(c.PrefixInsertionTrustAnchors)) + for _, anchor := range c.PrefixInsertionTrustAnchors { name, err := enc.NameFromStr(anchor) if err != nil { return err } - c.prefixInjectionTrustAnchorsN = append(c.prefixInjectionTrustAnchorsN, name) + c.prefixInsertionTrustAnchorsN = append(c.prefixInsertionTrustAnchorsN, name) } // Advertisement sync and data prefixes @@ -226,8 +226,8 @@ func (c *Config) TrustAnchorNames() []enc.Name { return c.trustAnchorsN } -func (c *Config) PrefixInjectionTrustAnchorNames() []enc.Name { - return c.prefixInjectionTrustAnchorsN +func (c *Config) PrefixInsertionTrustAnchorNames() []enc.Name { + return c.prefixInsertionTrustAnchorsN } func (c *Config) SchemaBytes() []byte { diff --git a/dv/dv.sample.yml b/dv/dv.sample.yml index 22813edd..6ea58698 100644 --- a/dv/dv.sample.yml +++ b/dv/dv.sample.yml @@ -12,16 +12,16 @@ dv: trust_anchors: - "/ndn/KEY/%27%C4%B2%2A%9F%7B%81%27/ndn/v=1651246789556" - # [optional] Trust schema for prefix injection + # [optional] Trust schema for prefix insertion # - If "insecure" is specified, security is disabled - # - If "deny" is specified, the prefix injection handler will be turned off + # - If "deny" is specified, the prefix insertion handler will be turned off # - Example: /absolute/path/to/schema.tlv - prefix_injection_schema: "insecure" - # [optional] Keychain URI for prefix injection - prefix_injection_keychain: "insecure" - # [optional] List of full names of all prefix injection trust anchors + prefix_insertion_schema: "insecure" + # [optional] Keychain URI for prefix insertion + prefix_insertion_keychain: "insecure" + # [optional] List of full names of all prefix insertion trust anchors # - There should be at least one trust anchor if the schema is not "insecure" or "deny" - prefix_injection_trust_anchors: [] + prefix_insertion_trust_anchors: [] # [optional] List of permanent neighbors # Example with all options: diff --git a/dv/dv/injection.go b/dv/dv/insertion.go similarity index 82% rename from dv/dv/injection.go rename to dv/dv/insertion.go index 9f7ed86f..ea766df3 100644 --- a/dv/dv/injection.go +++ b/dv/dv/insertion.go @@ -15,11 +15,11 @@ import ( "github.com/named-data/ndnd/std/types/optional" ) -func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { +func (dv *Router) onInsertion(args ndn.InterestHandlerArgs) { resError := &mgmt.ControlResponse{ Val: &mgmt.ControlResponseVal{ StatusCode: 400, - StatusText: "Failed to execute prefix injection", + StatusText: "Failed to execute prefix insertion", Params: nil, }, } @@ -35,7 +35,7 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { res.Encode(), signer) if err != nil { - log.Warn(dv, "Failed to make inject response Data", "err", err) + log.Warn(dv, "Failed to make Prefix Insertion response Data", "err", err) return } args.Reply(data.Wire) @@ -43,21 +43,21 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { // If there is no incoming face ID, we can't use this if !args.IncomingFaceId.IsSet() { - log.Warn(dv, "Received Prefix Injection with no incoming face ID, ignoring") + log.Warn(dv, "Received Prefix Insertion with no incoming face ID, ignoring") reply(resError) return } // Check if app param is present if args.Interest.AppParam() == nil { - log.Warn(dv, "Received Prefix Injection with no AppParam, ignoring") + log.Warn(dv, "Received Prefix Insertion with no AppParam, ignoring") reply(resError) return } - paParams, err := tlv.ParsePrefixInjection(enc.NewWireView(args.Interest.AppParam()), true) + paParams, err := tlv.ParsePrefixInsertion(enc.NewWireView(args.Interest.AppParam()), true) if err != nil { - log.Warn(dv, "Failed to parse Prefix Injection AppParam", "err", err) + log.Warn(dv, "Failed to parse Prefix Insertion AppParam", "err", err) reply(resError) return } @@ -67,7 +67,7 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { dCtx.Init() data, err := dCtx.Parse(enc.NewBufferView(paParams.ObjectWire), true) if err != nil { - log.Warn(dv, "Failed to parse Prefix Injection inner data", "err", err) + log.Warn(dv, "Failed to parse Prefix Insertion inner data", "err", err) reply(resError) return } @@ -93,13 +93,13 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { } // Validate signature - dv.prefixInjectionClient.ValidateExt(ndn.ValidateExtArgs{ + dv.prefixInsertionClient.ValidateExt(ndn.ValidateExtArgs{ Data: data, SigCovered: sigCov, Fetch: optional.Some(func(name enc.Name, config *ndn.InterestConfig, callback ndn.ExpressCallbackFunc) { for _, certCallback := range stapledCertCallbacks { if certCallback.Data.Name().Equal(name) { - dv.prefixInjectionClient.Engine().Post(func() { + dv.prefixInsertionClient.Engine().Post(func() { callback(certCallback) }) return @@ -107,12 +107,12 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { } config.NextHopId = optional.None[uint64]() - dv.prefixInjectionClient.ExpressR(ndn.ExpressRArgs{ + dv.prefixInsertionClient.ExpressR(ndn.ExpressRArgs{ Name: name, Config: config, Retries: 3, Callback: callback, - TryStore: dv.prefixInjectionClient.Store(), + TryStore: dv.prefixInsertionClient.Store(), }) }), Callback: func(valid bool, err error) { @@ -122,17 +122,17 @@ func (dv *Router) onInjection(args ndn.InterestHandlerArgs) { return } - res := dv.onPrefixInjectionObject(data, args.IncomingFaceId.Unwrap()) + res := dv.onPrefixInsertionObject(data, args.IncomingFaceId.Unwrap()) reply(res) }, }) } -func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt.ControlResponse { +func (dv *Router) onPrefixInsertionObject(object ndn.Data, faceId uint64) *mgmt.ControlResponse { resError := &mgmt.ControlResponse{ Val: &mgmt.ControlResponseVal{ StatusCode: 400, - StatusText: "Failed to execute prefix injection", + StatusText: "Failed to execute prefix insertion", Params: nil, }, } @@ -169,17 +169,17 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. return resError } - // Check if we've seen a newer version of this prefix injection + // Check if we've seen a newer version of this prefix insertion prefixHash := prefix.Hash() if lastVersion, exists := dv.seenPrefixVersions[prefixHash]; exists && lastVersion >= version { - log.Info(dv, "Rejecting older or duplicate prefix injection", + log.Info(dv, "Rejecting older or duplicate prefix insertion", "prefix", prefix, "version", version, "lastVersion", lastVersion) return &mgmt.ControlResponse{ Val: &mgmt.ControlResponseVal{ StatusCode: 409, - StatusText: "Older or duplicate prefix injection version", + StatusText: "Older or duplicate prefix insertion version", Params: nil, }, } @@ -188,7 +188,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. dv.seenPrefixVersions[prefixHash] = version piWire := object.Content() - params, err := tlv.ParsePrefixInjectionInnerContent(enc.NewWireView(piWire), true) + params, err := tlv.ParsePrefixInsertionInnerContent(enc.NewWireView(piWire), true) if err != nil { log.Warn(dv, "Failed to parse prefix announcement object", "err", err) return resError @@ -211,7 +211,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. now := time.Now().UTC() if now.Before(notBefore) || now.After(notAfter) { - log.Info(dv, "Prefix injection outside validity period", + log.Info(dv, "Prefix insertion outside validity period", "prefix", prefix, "notBefore", notBefore, "notAfter", notAfter, @@ -219,7 +219,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. return &mgmt.ControlResponse{ Val: &mgmt.ControlResponseVal{ StatusCode: 403, - StatusText: "Prefix injection outside validity period", + StatusText: "Prefix insertion outside validity period", Params: nil, }, } @@ -273,7 +273,7 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. Args: &mgmt.ControlArgs{ Name: prefix, FaceId: optional.Some(faceId), - Origin: optional.Some(config.PrefixInjOrigin), + Origin: optional.Some(config.PrefixInsOrigin), Cost: optional.Some(cost), }, Retries: 3, @@ -292,11 +292,11 @@ func (dv *Router) onPrefixInjectionObject(object ndn.Data, faceId uint64) *mgmt. return &mgmt.ControlResponse{ Val: &mgmt.ControlResponseVal{ StatusCode: 200, - StatusText: "Prefix Injection command successful", + StatusText: "Prefix Insertion command successful", Params: &mgmt.ControlArgs{ Name: prefix, FaceId: optional.Some(faceId), - Origin: optional.Some(config.PrefixInjOrigin), + Origin: optional.Some(config.PrefixInsOrigin), Cost: optional.Some(cost), }, }, diff --git a/dv/dv/router.go b/dv/dv/router.go index 259527aa..f70dac05 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -33,10 +33,10 @@ type Router struct { trust *sec.TrustConfig // object client client ndn.Client - // whether to do prefix injection - enablePrefixInjection bool - // prefix injection client - prefixInjectionClient ndn.Client + // whether to do prefix insertion + enablePrefixInsertion bool + // prefix insertion client + prefixInsertionClient ndn.Client // nfd management thread nfdc *nfdc.NfdMgmtThread // single mutex for all operations @@ -66,7 +66,7 @@ type Router struct { // forwarding table fib *table.Fib - // map to track seen prefix injection versions (prefix hash -> version) + // map to track seen prefix insertion versions (prefix hash -> version) seenPrefixVersions map[uint64]uint64 } @@ -104,19 +104,19 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { trust.UseDataNameFwHint = true } - enablePrefixInjection := config.PrefixInjectionSchemaPath != "deny" - prefixInjectionStore := storage.NewMemoryStore() - var prefixInjectionTrust *sec.TrustConfig = nil - if !enablePrefixInjection { - log.Warn(nil, "Prefix injection is disabled") - } else if config.PrefixInjectionSchemaPath == "insecure" || config.PrefixInjectionKeychainUri == "insecure" { - log.Warn(nil, "Prefix injection module is in allow-all mode") + enablePrefixInsertion := config.PrefixInsertionSchemaPath != "deny" + prefixInsertionStore := storage.NewMemoryStore() + var prefixInsertionTrust *sec.TrustConfig = nil + if !enablePrefixInsertion { + log.Warn(nil, "Prefix insertion is disabled") + } else if config.PrefixInsertionSchemaPath == "insecure" || config.PrefixInsertionKeychainUri == "insecure" { + log.Warn(nil, "Prefix insertion module is in allow-all mode") } else { - kc, err := keychain.NewKeyChain(config.PrefixInjectionKeychainUri, prefixInjectionStore) + kc, err := keychain.NewKeyChain(config.PrefixInsertionKeychainUri, prefixInsertionStore) if err != nil { return nil, err } - schemaData, err := os.ReadFile(config.PrefixInjectionSchemaPath) + schemaData, err := os.ReadFile(config.PrefixInsertionSchemaPath) if err != nil { return nil, err } @@ -124,8 +124,8 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { if err != nil { return nil, err } - anchors := config.PrefixInjectionTrustAnchorNames() - prefixInjectionTrust, err = sec.NewTrustConfig(kc, schema, anchors) + anchors := config.PrefixInsertionTrustAnchorNames() + prefixInsertionTrust, err = sec.NewTrustConfig(kc, schema, anchors) if err != nil { return nil, err } @@ -137,8 +137,8 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { config: config, trust: trust, client: object.NewClient(engine, store, trust), - enablePrefixInjection: enablePrefixInjection, - prefixInjectionClient: object.NewClient(engine, prefixInjectionStore, prefixInjectionTrust), + enablePrefixInsertion: enablePrefixInsertion, + prefixInsertionClient: object.NewClient(engine, prefixInsertionStore, prefixInsertionTrust), nfdc: nfdc.NewNfdMgmtThread(engine), mutex: sync.Mutex{}, seenPrefixVersions: make(map[uint64]uint64), @@ -277,13 +277,13 @@ func (dv *Router) register() (err error) { return err } - injectPrefix := enc.NewGenericComponent("routing"). - Append(enc.NewGenericComponent("inject")) + insertPrefix := enc.NewGenericComponent("routing"). + Append(enc.NewGenericComponent("insert")) - if dv.enablePrefixInjection { - err = dv.engine.AttachHandler(injectPrefix, + if dv.enablePrefixInsertion { + err = dv.engine.AttachHandler(insertPrefix, func(args ndn.InterestHandlerArgs) { - go dv.onInjection(args) + go dv.onInsertion(args) }) if err != nil { return err @@ -298,8 +298,8 @@ func (dv *Router) register() (err error) { dv.pfxSvs.DataPrefix(), dv.config.MgmtPrefix(), } - if dv.enablePrefixInjection { - pfxs = append(pfxs, injectPrefix) + if dv.enablePrefixInsertion { + pfxs = append(pfxs, insertPrefix) } for _, prefix := range pfxs { diff --git a/dv/tlv/definitions.go b/dv/tlv/definitions.go index b305a305..f8d0c269 100644 --- a/dv/tlv/definitions.go +++ b/dv/tlv/definitions.go @@ -73,14 +73,14 @@ type Status struct { NFibEntries uint64 `tlv:"0x19B"` } -type PrefixInjection struct { +type PrefixInsertion struct { //+field:sequence:[]byte:binary:[]byte StapledCertificates [][]byte `tlv:"0x216"` //+field:binary ObjectWire []byte `tlv:"0x06"` } -type PrefixInjectionInnerContent struct { +type PrefixInsertionInnerContent struct { //+field:natural ExpirationPeriod uint64 `tlv:"0x6d"` //+field:struct:spec_2022.ValidityPeriod diff --git a/dv/tlv/zz_generated.go b/dv/tlv/zz_generated.go index 22fce3a6..c69928ff 100644 --- a/dv/tlv/zz_generated.go +++ b/dv/tlv/zz_generated.go @@ -1685,17 +1685,17 @@ func ParseStatus(reader enc.WireView, ignoreCritical bool) (*Status, error) { return context.Parse(reader, ignoreCritical) } -type PrefixInjectionEncoder struct { +type PrefixInsertionEncoder struct { Length uint StapledCertificates_subencoder []struct { } } -type PrefixInjectionParsingContext struct { +type PrefixInsertionParsingContext struct { } -func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { +func (encoder *PrefixInsertionEncoder) Init(value *PrefixInsertion) { { StapledCertificates_l := len(value.StapledCertificates) encoder.StapledCertificates_subencoder = make([]struct { @@ -1748,11 +1748,11 @@ func (encoder *PrefixInjectionEncoder) Init(value *PrefixInjection) { } -func (context *PrefixInjectionParsingContext) Init() { +func (context *PrefixInsertionParsingContext) Init() { } -func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf []byte) { +func (encoder *PrefixInsertionEncoder) EncodeInto(value *PrefixInsertion, buf []byte) { pos := uint(0) @@ -1789,7 +1789,7 @@ func (encoder *PrefixInjectionEncoder) EncodeInto(value *PrefixInjection, buf [] } } -func (encoder *PrefixInjectionEncoder) Encode(value *PrefixInjection) enc.Wire { +func (encoder *PrefixInsertionEncoder) Encode(value *PrefixInsertion) enc.Wire { wire := make(enc.Wire, 1) wire[0] = make([]byte, encoder.Length) @@ -1799,7 +1799,7 @@ func (encoder *PrefixInjectionEncoder) Encode(value *PrefixInjection) enc.Wire { return wire } -func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { +func (context *PrefixInsertionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInsertion, error) { var handled_StapledCertificates bool = false var handled_ObjectWire bool = false @@ -1807,7 +1807,7 @@ func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreC progress := -1 _ = progress - value := &PrefixInjection{} + value := &PrefixInsertion{} var err error var startPos int for { @@ -1889,33 +1889,33 @@ func (context *PrefixInjectionParsingContext) Parse(reader enc.WireView, ignoreC return value, nil } -func (value *PrefixInjection) Encode() enc.Wire { - encoder := PrefixInjectionEncoder{} +func (value *PrefixInsertion) Encode() enc.Wire { + encoder := PrefixInsertionEncoder{} encoder.Init(value) return encoder.Encode(value) } -func (value *PrefixInjection) Bytes() []byte { +func (value *PrefixInsertion) Bytes() []byte { return value.Encode().Join() } -func ParsePrefixInjection(reader enc.WireView, ignoreCritical bool) (*PrefixInjection, error) { - context := PrefixInjectionParsingContext{} +func ParsePrefixInsertion(reader enc.WireView, ignoreCritical bool) (*PrefixInsertion, error) { + context := PrefixInsertionParsingContext{} context.Init() return context.Parse(reader, ignoreCritical) } -type PrefixInjectionInnerContentEncoder struct { +type PrefixInsertionInnerContentEncoder struct { Length uint ValidityPeriod_encoder spec_2022.ValidityPeriodEncoder } -type PrefixInjectionInnerContentParsingContext struct { +type PrefixInsertionInnerContentParsingContext struct { ValidityPeriod_context spec_2022.ValidityPeriodParsingContext } -func (encoder *PrefixInjectionInnerContentEncoder) Init(value *PrefixInjectionInnerContent) { +func (encoder *PrefixInsertionInnerContentEncoder) Init(value *PrefixInsertionInnerContent) { if value.ValidityPeriod != nil { encoder.ValidityPeriod_encoder.Init(value.ValidityPeriod) @@ -1937,13 +1937,13 @@ func (encoder *PrefixInjectionInnerContentEncoder) Init(value *PrefixInjectionIn } -func (context *PrefixInjectionInnerContentParsingContext) Init() { +func (context *PrefixInsertionInnerContentParsingContext) Init() { context.ValidityPeriod_context.Init() } -func (encoder *PrefixInjectionInnerContentEncoder) EncodeInto(value *PrefixInjectionInnerContent, buf []byte) { +func (encoder *PrefixInsertionInnerContentEncoder) EncodeInto(value *PrefixInsertionInnerContent, buf []byte) { pos := uint(0) @@ -1972,7 +1972,7 @@ func (encoder *PrefixInjectionInnerContentEncoder) EncodeInto(value *PrefixInjec } } -func (encoder *PrefixInjectionInnerContentEncoder) Encode(value *PrefixInjectionInnerContent) enc.Wire { +func (encoder *PrefixInsertionInnerContentEncoder) Encode(value *PrefixInsertionInnerContent) enc.Wire { wire := make(enc.Wire, 1) wire[0] = make([]byte, encoder.Length) @@ -1982,7 +1982,7 @@ func (encoder *PrefixInjectionInnerContentEncoder) Encode(value *PrefixInjection return wire } -func (context *PrefixInjectionInnerContentParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { +func (context *PrefixInsertionInnerContentParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInsertionInnerContent, error) { var handled_ExpirationPeriod bool = false var handled_ValidityPeriod bool = false @@ -1991,7 +1991,7 @@ func (context *PrefixInjectionInnerContentParsingContext) Parse(reader enc.WireV progress := -1 _ = progress - value := &PrefixInjectionInnerContent{} + value := &PrefixInsertionInnerContent{} var err error var startPos int for { @@ -2096,18 +2096,18 @@ func (context *PrefixInjectionInnerContentParsingContext) Parse(reader enc.WireV return value, nil } -func (value *PrefixInjectionInnerContent) Encode() enc.Wire { - encoder := PrefixInjectionInnerContentEncoder{} +func (value *PrefixInsertionInnerContent) Encode() enc.Wire { + encoder := PrefixInsertionInnerContentEncoder{} encoder.Init(value) return encoder.Encode(value) } -func (value *PrefixInjectionInnerContent) Bytes() []byte { +func (value *PrefixInsertionInnerContent) Bytes() []byte { return value.Encode().Join() } -func ParsePrefixInjectionInnerContent(reader enc.WireView, ignoreCritical bool) (*PrefixInjectionInnerContent, error) { - context := PrefixInjectionInnerContentParsingContext{} +func ParsePrefixInsertionInnerContent(reader enc.WireView, ignoreCritical bool) (*PrefixInsertionInnerContent, error) { + context := PrefixInsertionInnerContentParsingContext{} context.Init() return context.Parse(reader, ignoreCritical) } diff --git a/std/ndn/mgmt_2022/route.go b/std/ndn/mgmt_2022/route.go index f6aa7e7d..ea9158c6 100644 --- a/std/ndn/mgmt_2022/route.go +++ b/std/ndn/mgmt_2022/route.go @@ -31,7 +31,7 @@ const ( RouteOriginStatic RouteOrigin = 255 RouteOriginNLSR RouteOrigin = 128 RouteOriginPrefixAnn RouteOrigin = 129 - RouteOriginPrefixInj RouteOrigin = 130 + RouteOriginPrefixIns RouteOrigin = 130 RouteOriginClient RouteOrigin = 65 RouteOriginAutoreg RouteOrigin = 64 RouteOriginAutoconf RouteOrigin = 66 From 87f28409cd96f0d186d270ca9dcf611279d4d652 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:34:58 -0700 Subject: [PATCH 27/31] use time format constant from spec --- dv/dv/insertion.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dv/dv/insertion.go b/dv/dv/insertion.go index ea766df3..9d50b16a 100644 --- a/dv/dv/insertion.go +++ b/dv/dv/insertion.go @@ -197,13 +197,12 @@ func (dv *Router) onPrefixInsertionObject(object ndn.Data, faceId uint64) *mgmt. // Check validity period if it exists expirationPeriod := params.ExpirationPeriod if params.ValidityPeriod != nil { - const timeFormat = "20060102T150405" // Format for YYYYMMDDThhmmss - notBefore, err := time.Parse(timeFormat, params.ValidityPeriod.NotBefore) + notBefore, err := time.Parse(spec.TimeFmt, params.ValidityPeriod.NotBefore) if err != nil { log.Warn(dv, "Failed to parse NotBefore time", "err", err, "value", params.ValidityPeriod.NotBefore) return resError } - notAfter, err := time.Parse(timeFormat, params.ValidityPeriod.NotAfter) + notAfter, err := time.Parse(spec.TimeFmt, params.ValidityPeriod.NotAfter) if err != nil { log.Warn(dv, "Failed to parse NotAfter time", "err", err, "value", params.ValidityPeriod.NotAfter) return resError From 803ef78276363706b89205aca92eb9b6a974b2aa Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Tue, 17 Jun 2025 10:57:55 -0700 Subject: [PATCH 28/31] rename TLV inside PrefixInsertion to proper name --- dv/dv/insertion.go | 2 +- dv/tlv/definitions.go | 2 +- dv/tlv/zz_generated.go | 26 +++++++++++++------------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dv/dv/insertion.go b/dv/dv/insertion.go index 9d50b16a..bf9a83df 100644 --- a/dv/dv/insertion.go +++ b/dv/dv/insertion.go @@ -65,7 +65,7 @@ func (dv *Router) onInsertion(args ndn.InterestHandlerArgs) { // Decode Prefix Announcement Object dCtx := spec.DataParsingContext{} dCtx.Init() - data, err := dCtx.Parse(enc.NewBufferView(paParams.ObjectWire), true) + data, err := dCtx.Parse(enc.NewBufferView(paParams.Data), true) if err != nil { log.Warn(dv, "Failed to parse Prefix Insertion inner data", "err", err) reply(resError) diff --git a/dv/tlv/definitions.go b/dv/tlv/definitions.go index f8d0c269..cc5205de 100644 --- a/dv/tlv/definitions.go +++ b/dv/tlv/definitions.go @@ -77,7 +77,7 @@ type PrefixInsertion struct { //+field:sequence:[]byte:binary:[]byte StapledCertificates [][]byte `tlv:"0x216"` //+field:binary - ObjectWire []byte `tlv:"0x06"` + Data []byte `tlv:"0x06"` } type PrefixInsertionInnerContent struct { diff --git a/dv/tlv/zz_generated.go b/dv/tlv/zz_generated.go index c69928ff..53315c93 100644 --- a/dv/tlv/zz_generated.go +++ b/dv/tlv/zz_generated.go @@ -1739,10 +1739,10 @@ func (encoder *PrefixInsertionEncoder) Init(value *PrefixInsertion) { } } } - if value.ObjectWire != nil { + if value.Data != nil { l += 1 - l += uint(enc.TLNum(len(value.ObjectWire)).EncodingLength()) - l += uint(len(value.ObjectWire)) + l += uint(enc.TLNum(len(value.Data)).EncodingLength()) + l += uint(len(value.Data)) } encoder.Length = l @@ -1780,12 +1780,12 @@ func (encoder *PrefixInsertionEncoder) EncodeInto(value *PrefixInsertion, buf [] } } } - if value.ObjectWire != nil { + if value.Data != nil { buf[pos] = byte(6) pos += 1 - pos += uint(enc.TLNum(len(value.ObjectWire)).EncodeInto(buf[pos:])) - copy(buf[pos:], value.ObjectWire) - pos += uint(len(value.ObjectWire)) + pos += uint(enc.TLNum(len(value.Data)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.Data) + pos += uint(len(value.Data)) } } @@ -1802,7 +1802,7 @@ func (encoder *PrefixInsertionEncoder) Encode(value *PrefixInsertion) enc.Wire { func (context *PrefixInsertionParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*PrefixInsertion, error) { var handled_StapledCertificates bool = false - var handled_ObjectWire bool = false + var handled_Data bool = false progress := -1 _ = progress @@ -1853,9 +1853,9 @@ func (context *PrefixInsertionParsingContext) Parse(reader enc.WireView, ignoreC case 6: if true { handled = true - handled_ObjectWire = true - value.ObjectWire = make([]byte, l) - _, err = reader.ReadFull(value.ObjectWire) + handled_Data = true + value.Data = make([]byte, l) + _, err = reader.ReadFull(value.Data) } default: if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { @@ -1878,8 +1878,8 @@ func (context *PrefixInsertionParsingContext) Parse(reader enc.WireView, ignoreC if !handled_StapledCertificates && err == nil { // sequence - skip } - if !handled_ObjectWire && err == nil { - value.ObjectWire = nil + if !handled_Data && err == nil { + value.Data = nil } if err != nil { From 042921d9dea1ba03a9e71a4e4e0da7e043e064ed Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Tue, 17 Jun 2025 11:05:46 -0700 Subject: [PATCH 29/31] do not construct prefix injection client if prefix injection is disabled --- dv/dv/router.go | 57 ++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/dv/dv/router.go b/dv/dv/router.go index f70dac05..ecb29853 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -105,30 +105,34 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { } enablePrefixInsertion := config.PrefixInsertionSchemaPath != "deny" - prefixInsertionStore := storage.NewMemoryStore() - var prefixInsertionTrust *sec.TrustConfig = nil - if !enablePrefixInsertion { - log.Warn(nil, "Prefix insertion is disabled") - } else if config.PrefixInsertionSchemaPath == "insecure" || config.PrefixInsertionKeychainUri == "insecure" { - log.Warn(nil, "Prefix insertion module is in allow-all mode") - } else { - kc, err := keychain.NewKeyChain(config.PrefixInsertionKeychainUri, prefixInsertionStore) - if err != nil { - return nil, err - } - schemaData, err := os.ReadFile(config.PrefixInsertionSchemaPath) - if err != nil { - return nil, err - } - schema, err := trust_schema.NewLvsSchema(schemaData) - if err != nil { - return nil, err - } - anchors := config.PrefixInsertionTrustAnchorNames() - prefixInsertionTrust, err = sec.NewTrustConfig(kc, schema, anchors) - if err != nil { - return nil, err + var prefixInsertionClient ndn.Client + if enablePrefixInsertion { + prefixInsertionStore := storage.NewMemoryStore() + var prefixInsertionTrust *sec.TrustConfig = nil + if config.PrefixInsertionSchemaPath == "insecure" || config.PrefixInsertionKeychainUri == "insecure" { + log.Warn(nil, "Prefix insertion module is in allow-all mode") + } else { + kc, err := keychain.NewKeyChain(config.PrefixInsertionKeychainUri, prefixInsertionStore) + if err != nil { + return nil, err + } + schemaData, err := os.ReadFile(config.PrefixInsertionSchemaPath) + if err != nil { + return nil, err + } + schema, err := trust_schema.NewLvsSchema(schemaData) + if err != nil { + return nil, err + } + anchors := config.PrefixInsertionTrustAnchorNames() + prefixInsertionTrust, err = sec.NewTrustConfig(kc, schema, anchors) + if err != nil { + return nil, err + } } + prefixInsertionClient = object.NewClient(engine, prefixInsertionStore, prefixInsertionTrust) + } else { + log.Warn(nil, "Prefix insertion is disabled") } // Create the DV router @@ -138,7 +142,7 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { trust: trust, client: object.NewClient(engine, store, trust), enablePrefixInsertion: enablePrefixInsertion, - prefixInsertionClient: object.NewClient(engine, prefixInsertionStore, prefixInsertionTrust), + prefixInsertionClient: prefixInsertionClient, nfdc: nfdc.NewNfdMgmtThread(engine), mutex: sync.Mutex{}, seenPrefixVersions: make(map[uint64]uint64), @@ -190,6 +194,11 @@ func (dv *Router) Start() (err error) { dv.client.Start() defer dv.client.Stop() + if dv.enablePrefixInsertion { + dv.prefixInsertionClient.Start() + defer dv.prefixInsertionClient.Stop() + } + // Start management thread go dv.nfdc.Start() defer dv.nfdc.Stop() From 28995d896cd2d4a717b9a4412f861beccc65f4e4 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Tue, 17 Jun 2025 11:09:28 -0700 Subject: [PATCH 30/31] reduce collision by using binary string for hashing --- dv/dv/insertion.go | 6 +++--- dv/dv/router.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dv/dv/insertion.go b/dv/dv/insertion.go index bf9a83df..73131e34 100644 --- a/dv/dv/insertion.go +++ b/dv/dv/insertion.go @@ -170,8 +170,8 @@ func (dv *Router) onPrefixInsertionObject(object ndn.Data, faceId uint64) *mgmt. } // Check if we've seen a newer version of this prefix insertion - prefixHash := prefix.Hash() - if lastVersion, exists := dv.seenPrefixVersions[prefixHash]; exists && lastVersion >= version { + prefixStr := string(prefix.Bytes()) + if lastVersion, exists := dv.seenPrefixVersions[prefixStr]; exists && lastVersion >= version { log.Info(dv, "Rejecting older or duplicate prefix insertion", "prefix", prefix, "version", version, @@ -185,7 +185,7 @@ func (dv *Router) onPrefixInsertionObject(object ndn.Data, faceId uint64) *mgmt. } } - dv.seenPrefixVersions[prefixHash] = version + dv.seenPrefixVersions[prefixStr] = version piWire := object.Content() params, err := tlv.ParsePrefixInsertionInnerContent(enc.NewWireView(piWire), true) diff --git a/dv/dv/router.go b/dv/dv/router.go index ecb29853..4f011f12 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -66,8 +66,8 @@ type Router struct { // forwarding table fib *table.Fib - // map to track seen prefix insertion versions (prefix hash -> version) - seenPrefixVersions map[uint64]uint64 + // map to track seen prefix insertion versions (prefix string -> version) + seenPrefixVersions map[string]uint64 } // Create a new DV router. @@ -145,7 +145,7 @@ func NewRouter(config *config.Config, engine ndn.Engine) (*Router, error) { prefixInsertionClient: prefixInsertionClient, nfdc: nfdc.NewNfdMgmtThread(engine), mutex: sync.Mutex{}, - seenPrefixVersions: make(map[uint64]uint64), + seenPrefixVersions: make(map[string]uint64), } // Initialize advertisement module From 4b2447d5f945fcda6cbec01d44aec8722c0116c8 Mon Sep 17 00:00:00 2001 From: jaczhi <54284925+jaczhi@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:44:07 -0700 Subject: [PATCH 31/31] revert unncessary start logic --- dv/dv/router.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dv/dv/router.go b/dv/dv/router.go index 4f011f12..72788870 100644 --- a/dv/dv/router.go +++ b/dv/dv/router.go @@ -194,11 +194,6 @@ func (dv *Router) Start() (err error) { dv.client.Start() defer dv.client.Stop() - if dv.enablePrefixInsertion { - dv.prefixInsertionClient.Start() - defer dv.prefixInsertionClient.Stop() - } - // Start management thread go dv.nfdc.Start() defer dv.nfdc.Stop()