@@ -111,50 +111,21 @@ func (s *Service) getNewDirectorRoots(uptane uptaneClient, currentVersion uint64
111
111
return roots , nil
112
112
}
113
113
114
- func (s * Service ) getTargetFiles (uptane uptaneClient , products []rdata.Product , cachedTargetFiles []* pbgo.TargetFileMeta ) ([]* pbgo.File , error ) {
115
- productSet := make (map [rdata.Product ]struct {})
116
- for _ , product := range products {
117
- productSet [product ] = struct {}{}
118
- }
119
- targets , err := uptane .Targets ()
114
+ func (s * Service ) getTargetFiles (uptaneClient uptaneClient , targetFilePaths []string ) ([]* pbgo.File , error ) {
115
+ files , err := uptaneClient .TargetFiles (targetFilePaths )
120
116
if err != nil {
121
117
return nil , err
122
118
}
123
- cachedTargets := make (map [string ]data.FileMeta )
124
- for _ , cachedTarget := range cachedTargetFiles {
125
- hashes := make (data.Hashes )
126
- for _ , hash := range cachedTarget .Hashes {
127
- h , err := hex .DecodeString (hash .Hash )
128
- if err != nil {
129
- return nil , err
130
- }
131
- hashes [hash .Algorithm ] = h
132
- }
133
- cachedTargets [cachedTarget .Path ] = data.FileMeta {
134
- Hashes : hashes ,
135
- Length : cachedTarget .Length ,
136
- }
137
- }
119
+
138
120
var configFiles []* pbgo.File
139
- for targetPath , targetMeta := range targets {
140
- configPathMeta , err := rdata .ParseConfigPath (targetPath )
141
- if err != nil {
142
- return nil , err
143
- }
144
- if _ , inClientProducts := productSet [rdata .Product (configPathMeta .Product )]; inClientProducts {
145
- if notEqualErr := tufutil .FileMetaEqual (cachedTargets [targetPath ], targetMeta .FileMeta ); notEqualErr == nil {
146
- continue
147
- }
148
- fileContents , err := uptane .TargetFile (targetPath )
149
- if err != nil {
150
- return nil , err
151
- }
152
- configFiles = append (configFiles , & pbgo.File {
153
- Path : targetPath ,
154
- Raw : fileContents ,
155
- })
156
- }
121
+ for path , contents := range files {
122
+ // Note: This unconditionally succeeds as long as we don't change bufferDestination earlier
123
+ configFiles = append (configFiles , & pbgo.File {
124
+ Path : path ,
125
+ Raw : contents ,
126
+ })
157
127
}
128
+
158
129
return configFiles , nil
159
130
}
160
131
@@ -211,6 +182,7 @@ type uptaneClient interface {
211
182
StoredOrgUUID () (string , error )
212
183
Targets () (data.TargetFiles , error )
213
184
TargetFile (path string ) ([]byte , error )
185
+ TargetFiles (files []string ) (map [string ][]byte , error )
214
186
TargetsMeta () ([]byte , error )
215
187
TargetsCustom () ([]byte , error )
216
188
TUFVersionState () (uptane.TUFVersions , error )
@@ -828,36 +800,30 @@ func (s *CoreAgentService) ClientGetConfigs(_ context.Context, request *pbgo.Cli
828
800
if err != nil {
829
801
return nil , err
830
802
}
831
- targetsRaw , err := s .uptane .TargetsMeta ()
803
+
804
+ directorTargets , err := s .uptane .Targets ()
832
805
if err != nil {
833
806
return nil , err
834
807
}
835
- targetFiles , err := s . getTargetFiles ( s . uptane , rdata . StringListToProduct ( request .Client . Products ), request . CachedTargetFiles )
808
+ matchedClientConfigs , err := executeTracerPredicates ( request .Client , directorTargets )
836
809
if err != nil {
837
810
return nil , err
838
811
}
839
812
840
- directorTargets , err := s . uptane . Targets ( )
813
+ neededFiles , err := filterNeededTargetFiles ( matchedClientConfigs , request . CachedTargetFiles , directorTargets )
841
814
if err != nil {
842
815
return nil , err
843
816
}
844
- matchedClientConfigs , err := executeTracerPredicates (request .Client , directorTargets )
817
+
818
+ targetFiles , err := s .getTargetFiles (s .uptane , neededFiles )
845
819
if err != nil {
846
820
return nil , err
847
821
}
848
822
849
- // filter files to only return the ones that predicates marked for this client
850
- matchedConfigsMap := make (map [string ]interface {})
851
- for _ , configPointer := range matchedClientConfigs {
852
- matchedConfigsMap [configPointer ] = struct {}{}
853
- }
854
- filteredFiles := make ([]* pbgo.File , 0 , len (matchedClientConfigs ))
855
- for _ , targetFile := range targetFiles {
856
- if _ , ok := matchedConfigsMap [targetFile .Path ]; ok {
857
- filteredFiles = append (filteredFiles , targetFile )
858
- }
823
+ targetsRaw , err := s .uptane .TargetsMeta ()
824
+ if err != nil {
825
+ return nil , err
859
826
}
860
-
861
827
canonicalTargets , err := enforceCanonicalJSON (targetsRaw )
862
828
if err != nil {
863
829
return nil , err
@@ -866,11 +832,42 @@ func (s *CoreAgentService) ClientGetConfigs(_ context.Context, request *pbgo.Cli
866
832
return & pbgo.ClientGetConfigsResponse {
867
833
Roots : roots ,
868
834
Targets : canonicalTargets ,
869
- TargetFiles : filteredFiles ,
835
+ TargetFiles : targetFiles ,
870
836
ClientConfigs : matchedClientConfigs ,
871
837
}, nil
872
838
}
873
839
840
+ func filterNeededTargetFiles (neededConfigs []string , cachedTargetFiles []* pbgo.TargetFileMeta , tufTargets data.TargetFiles ) ([]string , error ) {
841
+ // Build an O(1) lookup of cached target files
842
+ cachedTargetsMap := make (map [string ]data.FileMeta )
843
+ for _ , cachedTarget := range cachedTargetFiles {
844
+ hashes := make (data.Hashes )
845
+ for _ , hash := range cachedTarget .Hashes {
846
+ h , err := hex .DecodeString (hash .Hash )
847
+ if err != nil {
848
+ return nil , err
849
+ }
850
+ hashes [hash .Algorithm ] = h
851
+ }
852
+ cachedTargetsMap [cachedTarget .Path ] = data.FileMeta {
853
+ Hashes : hashes ,
854
+ Length : cachedTarget .Length ,
855
+ }
856
+ }
857
+
858
+ // We don't need to pull the raw contents if the client already has the exact version of the file cached
859
+ filteredList := make ([]string , 0 , len (neededConfigs ))
860
+ for _ , path := range neededConfigs {
861
+ if notEqualErr := tufutil .FileMetaEqual (cachedTargetsMap [path ], tufTargets [path ].FileMeta ); notEqualErr == nil {
862
+ continue
863
+ }
864
+
865
+ filteredList = append (filteredList , path )
866
+ }
867
+
868
+ return filteredList , nil
869
+ }
870
+
874
871
// ConfigGetState returns the state of the configuration and the director repos in the local store
875
872
func (s * CoreAgentService ) ConfigGetState () (* pbgo.GetStateConfigResponse , error ) {
876
873
state , err := s .uptane .State ()
@@ -1117,29 +1114,14 @@ func (c *HTTPClient) getUpdate(
1117
1114
if tufVersions .DirectorTargets == currentTargetsVersion {
1118
1115
return nil , nil
1119
1116
}
1120
- roots , err := c .getNewDirectorRoots (c .uptane , currentRootVersion , tufVersions .DirectorRoot )
1121
- if err != nil {
1122
- return nil , err
1123
- }
1124
- targetsRaw , err := c .uptane .TargetsMeta ()
1125
- if err != nil {
1126
- return nil , err
1127
- }
1128
- targetFiles , err := c .getTargetFiles (c .uptane , rdata .StringListToProduct (products ), cachedTargetFiles )
1129
- if err != nil {
1130
- return nil , err
1131
- }
1132
-
1133
- canonicalTargets , err := enforceCanonicalJSON (targetsRaw )
1134
- if err != nil {
1135
- return nil , err
1136
- }
1137
1117
1118
+ // Filter out files that either:
1119
+ // - don't correspond to the product list the client is requesting
1120
+ // - have expired
1138
1121
directorTargets , err := c .uptane .Targets ()
1139
1122
if err != nil {
1140
1123
return nil , err
1141
1124
}
1142
-
1143
1125
productsMap := make (map [string ]struct {})
1144
1126
for _ , product := range products {
1145
1127
productsMap [product ] = struct {}{}
@@ -1165,14 +1147,33 @@ func (c *HTTPClient) getUpdate(
1165
1147
1166
1148
configs = append (configs , path )
1167
1149
}
1150
+ span .SetTag ("configs.returned" , configs )
1151
+ span .SetTag ("configs.expired" , expiredConfigs )
1168
1152
1153
+ // Gather the files and map-ify them for the state data structure
1154
+ targetFiles , err := c .getTargetFiles (c .uptane , configs )
1155
+ if err != nil {
1156
+ return nil , err
1157
+ }
1169
1158
fileMap := make (map [string ][]byte , len (targetFiles ))
1170
1159
for _ , f := range targetFiles {
1171
1160
fileMap [f .Path ] = f .Raw
1172
1161
}
1173
1162
1174
- span .SetTag ("configs.returned" , configs )
1175
- span .SetTag ("configs.expired" , expiredConfigs )
1163
+ // Gather some TUF metadata files we need to send down
1164
+ roots , err := c .getNewDirectorRoots (c .uptane , currentRootVersion , tufVersions .DirectorRoot )
1165
+ if err != nil {
1166
+ return nil , err
1167
+ }
1168
+ targetsRaw , err := c .uptane .TargetsMeta ()
1169
+ if err != nil {
1170
+ return nil , err
1171
+ }
1172
+ canonicalTargets , err := enforceCanonicalJSON (targetsRaw )
1173
+ if err != nil {
1174
+ return nil , err
1175
+ }
1176
+
1176
1177
return & state.Update {
1177
1178
TUFRoots : roots ,
1178
1179
TUFTargets : canonicalTargets ,
0 commit comments