@@ -38,6 +38,22 @@ func returnError(w http.ResponseWriter, err error) {
38
38
fmt .Fprintf (w , `{"err":` + strconv .Quote (err .Error ())+ `}` )
39
39
}
40
40
41
+ func returnPathHandler (w http.ResponseWriter , pathJson []byte , segJson []byte , err error ) {
42
+ var buffer bytes.Buffer
43
+ buffer .WriteString (`{"src":"sciond"` )
44
+ if pathJson != nil {
45
+ buffer .WriteString (fmt .Sprintf (`,"paths":%s` , pathJson ))
46
+ }
47
+ if segJson != nil {
48
+ buffer .WriteString (fmt .Sprintf (`,"segments":%s` , segJson ))
49
+ }
50
+ if err != nil {
51
+ buffer .WriteString (fmt .Sprintf (`,"err":%s` , strconv .Quote (err .Error ())))
52
+ }
53
+ buffer .WriteString (`}` )
54
+ fmt .Fprintf (w , buffer .String ())
55
+ }
56
+
41
57
// sciond data sources and calls
42
58
43
59
// PathTopoHandler handles requests for paths, returning results from sciond.
@@ -78,34 +94,55 @@ func PathTopoHandler(w http.ResponseWriter, r *http.Request) {
78
94
}
79
95
}
80
96
81
- paths := getPaths (* clientCCAddr , * serverCCAddr )
82
- if len (paths ) == 0 {
83
- returnError (w , fmt .Errorf ("No paths from %s to %s" , clientCCAddr .IA ,
84
- serverCCAddr .IA ))
97
+ paths , err := getPathsJSON (* clientCCAddr , * serverCCAddr )
98
+ if CheckError (err ) {
99
+ returnError (w , err )
100
+ return
101
+ }
102
+ log .Debug ("PathTopoHandler:" , "paths" , string (paths ))
103
+
104
+ // Since segments data is supplimentary to paths data, if segments data
105
+ // fails, provide the error, but we must still allow paths data to return.
106
+ segments , err := getSegmentsJSON (* clientCCAddr )
107
+ if CheckError (err ) {
108
+ returnPathHandler (w , paths , nil , err )
85
109
return
86
110
}
111
+ log .Debug ("PathTopoHandler:" , "segments" , string (segments ))
87
112
88
- jsonPathInfo , _ := json . Marshal ( paths )
89
- log . Debug ( "PathTopoHandler:" , "jsonPathInfo" , string ( jsonPathInfo ))
113
+ returnPathHandler ( w , paths , segments , err )
114
+ }
90
115
116
+ func getSegmentsJSON (local snet.Addr ) ([]byte , error ) {
91
117
// load segments from paths database
92
- var dbSrcFile = findDBFilename (clientCCAddr .IA )
93
- dbTmpFile := copyDBToTemp (dbSrcFile )
118
+ var dbSrcFile = findDBFilename (local .IA )
119
+ dbTmpFile , err := copyDBToTemp (dbSrcFile )
120
+ if err != nil {
121
+ return nil , err
122
+ }
94
123
// since http.ListenAndServe() blocks, ensure we generate a local db object
95
124
// which will live only during the http call
96
- db := pathdb .InitDB (dbTmpFile )
125
+ db , err := pathdb .InitDB (dbTmpFile )
126
+ if err != nil {
127
+ return nil , err
128
+ }
97
129
defer func () {
98
130
pathdb .CloseDB (db )
99
131
removeAllDir (filepath .Dir (dbTmpFile ))
100
132
}()
101
- segTypes := pathdb .ReadSegTypesAll (db )
102
- segments := pathdb .ReadSegmentsAll (db , segTypes )
103
-
104
- jsonSegsInfo , _ := json .Marshal (segments )
105
- log .Debug ("PathTopoHandler:" , "jsonSegsInfo" , string (jsonSegsInfo ))
106
-
107
- fmt .Fprintf (w , fmt .Sprintf (`{"paths":%s,"segments":%s}` ,
108
- jsonPathInfo , jsonSegsInfo ))
133
+ segTypes , err := pathdb .ReadSegTypesAll (db )
134
+ if err != nil {
135
+ return nil , err
136
+ }
137
+ segments , err := pathdb .ReadSegmentsAll (db , segTypes )
138
+ if err != nil {
139
+ return nil , err
140
+ }
141
+ jsonSegsInfo , err := json .Marshal (segments )
142
+ if err != nil {
143
+ return nil , err
144
+ }
145
+ return jsonSegsInfo , nil
109
146
}
110
147
111
148
func findDBFilename (ia addr.IA ) string {
@@ -120,52 +157,60 @@ func findDBFilename(ia addr.IA) string {
120
157
}
121
158
122
159
// returns the name of the created file
123
- func copyDBToTemp (filename string ) string {
160
+ func copyDBToTemp (filename string ) ( string , error ) {
124
161
copyOneFile := func (dstDir , srcFileName string ) error {
125
162
src , err := os .Open (srcFileName )
126
- if CheckError ( err ) {
127
- return fmt . Errorf ( "Cannot open %s: %v" , srcFileName , err )
163
+ if err != nil {
164
+ return err
128
165
}
129
166
defer src .Close ()
130
167
dstFilename := filepath .Join (dstDir , filepath .Base (srcFileName ))
131
168
dst , err := os .Create (dstFilename )
132
- if CheckError ( err ) {
133
- return fmt . Errorf ( "Cannot open %s: %v" , dstFilename , err )
169
+ if err != nil {
170
+ return err
134
171
}
135
172
defer dst .Close ()
136
173
_ , err = io .Copy (dst , src )
137
- if CheckError ( err ) {
138
- return fmt . Errorf ( "Cannot copy %s to %s: %v" , srcFileName , dstFilename , err . Error ())
174
+ if err != nil {
175
+ return err
139
176
}
140
177
return nil
141
178
}
142
179
dirName , err := ioutil .TempDir ("/tmp" , "sciond_dump" )
143
- if CheckError ( err ) {
144
- return err . Error ()
180
+ if err != nil {
181
+ return "" , err
145
182
}
146
-
147
183
err = copyOneFile (dirName , filename )
148
- if CheckError ( err ) {
149
- fmt . Fprintf ( os . Stderr , "No panic: %v " , err )
184
+ if err != nil {
185
+ return " " , err
150
186
}
151
187
err = copyOneFile (dirName , filename + "-wal" )
152
- CheckError (err )
153
- return filepath .Join (dirName , filepath .Base (filename ))
188
+ if err != nil {
189
+ return "" , err
190
+ }
191
+ return filepath .Join (dirName , filepath .Base (filename )), nil
154
192
}
155
193
156
194
func removeAllDir (dirName string ) {
157
195
err := os .RemoveAll (dirName )
158
196
CheckError (err )
159
197
}
160
198
161
- func getPaths (local snet.Addr , remote snet.Addr ) [] * spathmeta. AppPath {
199
+ func getPathsJSON (local snet.Addr , remote snet.Addr ) ([] byte , error ) {
162
200
pathMgr := snet .DefNetwork .PathResolver ()
163
201
pathSet := pathMgr .Query (context .Background (), local .IA , remote .IA )
202
+ if len (pathSet ) == 0 {
203
+ return nil , fmt .Errorf ("No paths from %s to %s" , local .IA , remote .IA )
204
+ }
164
205
var appPaths []* spathmeta.AppPath
165
206
for _ , path := range pathSet {
166
207
appPaths = append (appPaths , path )
167
208
}
168
- return appPaths
209
+ jsonPathInfo , err := json .Marshal (appPaths )
210
+ if err != nil {
211
+ return nil , err
212
+ }
213
+ return jsonPathInfo , nil
169
214
}
170
215
171
216
// AsTopoHandler handles requests for AS data, returning results from sciond.
0 commit comments