@@ -4,16 +4,20 @@ import (
4
4
"bytes"
5
5
"context"
6
6
"encoding/json"
7
+ "errors"
7
8
"fmt"
9
+ "io"
8
10
"io/ioutil"
9
11
"net/http"
12
+ "os"
10
13
"path"
11
14
"path/filepath"
12
15
"runtime"
13
16
"strconv"
14
17
"strings"
15
18
16
19
log "github.com/inconshreveable/log15"
20
+ pathdb "github.com/netsec-ethz/scion-apps/webapp/models/path"
17
21
. "github.com/netsec-ethz/scion-apps/webapp/util"
18
22
"github.com/scionproto/scion/go/lib/addr"
19
23
"github.com/scionproto/scion/go/lib/common"
@@ -46,6 +50,11 @@ func PathTopoHandler(w http.ResponseWriter, r *http.Request) {
46
50
SPort , _ := strconv .Atoi (r .PostFormValue ("port_ser" ))
47
51
CPort , _ := strconv .Atoi (r .PostFormValue ("port_cli" ))
48
52
53
+ // src and dst must be different
54
+ if SIa == CIa {
55
+ returnError (w , errors .New ("Source IA and destination IA are the same." ))
56
+ return
57
+ }
49
58
optClient := fmt .Sprintf ("%s,[%s]:%d" , CIa , CAddr , CPort )
50
59
optServer := fmt .Sprintf ("%s,[%s]:%d" , SIa , SAddr , SPort )
51
60
clientCCAddr , _ := snet .AddrFromString (optClient )
@@ -79,7 +88,74 @@ func PathTopoHandler(w http.ResponseWriter, r *http.Request) {
79
88
jsonPathInfo , _ := json .Marshal (paths )
80
89
log .Debug ("PathTopoHandler:" , "jsonPathInfo" , string (jsonPathInfo ))
81
90
82
- fmt .Fprintf (w , fmt .Sprintf (`{"paths":%s}` , jsonPathInfo ))
91
+ // load segments from paths database
92
+ var dbSrcFile = findDBFilename (clientCCAddr .IA )
93
+ dbTmpFile := copyDBToTemp (dbSrcFile )
94
+ // since http.ListenAndServe() blocks, ensure we generate a local db object
95
+ // which will live only during the http call
96
+ db := pathdb .InitDB (dbTmpFile )
97
+ defer func () {
98
+ pathdb .CloseDB (db )
99
+ removeAllDir (filepath .Dir (dbTmpFile ))
100
+ }()
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 ))
109
+ }
110
+
111
+ func findDBFilename (ia addr.IA ) string {
112
+ filenames , err := filepath .Glob (filepath .Join (
113
+ GOPATH , SCIONROOT , "gen-cache" , "ps*path.db" ))
114
+ CheckError (err )
115
+ if len (filenames ) == 1 {
116
+ return filenames [0 ]
117
+ }
118
+ pathDBFileName := fmt .Sprintf ("ps%s-1.path.db" , ia .FileFmt (false ))
119
+ return filepath .Join (GOPATH , SCIONROOT , "gen-cache" , pathDBFileName )
120
+ }
121
+
122
+ // returns the name of the created file
123
+ func copyDBToTemp (filename string ) string {
124
+ copyOneFile := func (dstDir , srcFileName string ) error {
125
+ src , err := os .Open (srcFileName )
126
+ if CheckError (err ) {
127
+ return fmt .Errorf ("Cannot open %s: %v" , srcFileName , err )
128
+ }
129
+ defer src .Close ()
130
+ dstFilename := filepath .Join (dstDir , filepath .Base (srcFileName ))
131
+ dst , err := os .Create (dstFilename )
132
+ if CheckError (err ) {
133
+ return fmt .Errorf ("Cannot open %s: %v" , dstFilename , err )
134
+ }
135
+ defer dst .Close ()
136
+ _ , err = io .Copy (dst , src )
137
+ if CheckError (err ) {
138
+ return fmt .Errorf ("Cannot copy %s to %s: %v" , srcFileName , dstFilename , err .Error ())
139
+ }
140
+ return nil
141
+ }
142
+ dirName , err := ioutil .TempDir ("/tmp" , "sciond_dump" )
143
+ if CheckError (err ) {
144
+ return err .Error ()
145
+ }
146
+
147
+ err = copyOneFile (dirName , filename )
148
+ if CheckError (err ) {
149
+ fmt .Fprintf (os .Stderr , "No panic: %v" , err )
150
+ }
151
+ err = copyOneFile (dirName , filename + "-wal" )
152
+ CheckError (err )
153
+ return filepath .Join (dirName , filepath .Base (filename ))
154
+ }
155
+
156
+ func removeAllDir (dirName string ) {
157
+ err := os .RemoveAll (dirName )
158
+ CheckError (err )
83
159
}
84
160
85
161
func getPaths (local snet.Addr , remote snet.Addr ) []* spathmeta.AppPath {
0 commit comments