Skip to content

Commit 268146d

Browse files
committed
Merge branch 'master' of https://github.com/N2D4/scion-apps
2 parents 055398f + 4ffb67b commit 268146d

File tree

12 files changed

+546
-49
lines changed

12 files changed

+546
-49
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ webapp.db
2626
webapp/data
2727
.webapp
2828

29+
# IDE project files
30+
.jshintrc
31+
.project
32+
.settings/
33+
2934
*.log
3035

3136
# vendor directory

webapp/lib/config.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,21 @@ func GetLocalIa() string {
4343
return strings.Replace(strings.TrimSpace(string(b)), "_", ":", -1)
4444
}
4545

46+
func GetCliIaDef() string {
47+
return cliIaDef
48+
}
49+
4650
// Makes interfaces sortable, by preferred name
4751
type byPrefInterface []net.Interface
4852

4953
func isInterfaceEnp(c net.Interface) bool {
5054
return strings.HasPrefix(c.Name, "enp")
5155
}
5256

57+
func isInterfaceLocal(c net.Interface) bool {
58+
return strings.HasPrefix(c.Name, "lo")
59+
}
60+
5361
func (c byPrefInterface) Len() int {
5462
return len(c)
5563
}
@@ -59,23 +67,29 @@ func (c byPrefInterface) Swap(i, j int) {
5967
}
6068

6169
func (c byPrefInterface) Less(i, j int) bool {
62-
// sort "enp" interfaces first, then alphabetically
70+
// sort "enp" interfaces first, then "lo", then alphabetically
6371
if isInterfaceEnp(c[i]) && !isInterfaceEnp(c[j]) {
6472
return true
6573
}
6674
if !isInterfaceEnp(c[i]) && isInterfaceEnp(c[j]) {
6775
return false
6876
}
77+
if isInterfaceLocal(c[i]) && !isInterfaceLocal(c[j]) {
78+
return true
79+
}
80+
if !isInterfaceLocal(c[i]) && isInterfaceLocal(c[j]) {
81+
return false
82+
}
6983
return c[i].Name < c[j].Name
7084
}
7185

7286
// GenServerNodeDefaults creates server defaults for localhost testing
7387
func GenServerNodeDefaults(srcpath string) {
7488
serFp := path.Join(srcpath, cfgFileSerUser)
7589
jsonBuf := []byte(`{ `)
76-
json := []byte(`"bwtester": [{"name":"localhost","isdas":"` +
90+
json := []byte(`"bwtester": [{"name":"lo ` + serIaDef + `","isdas":"` +
7791
serIaDef + `", "addr":"` + serDefAddr + `","port":` + serPortDefBwt +
78-
`},{"name":"test1","isdas":"2-ff00:0:222", "addr":"127.0.0.22","port":30101}], `)
92+
`},{"name":"lo 2-ff00:0:222","isdas":"2-ff00:0:222", "addr":"127.0.0.22","port":30101}], `)
7993
jsonBuf = append(jsonBuf, json...)
8094
json = []byte(`"camerapp": [{"name":"localhost","isdas":"` +
8195
serIaDef + `", "addr":"` + serDefAddr + `","port":` + serPortDefImg + `}], `)

webapp/lib/health.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func HealthCheckHandler(w http.ResponseWriter, r *http.Request, srcpath string)
5353
fmt.Fprintf(w, `{ "err": "`+err.Error()+`" }`)
5454
return
5555
}
56-
log.Info(string(raw))
56+
log.Debug("HealthCheckHandler", "resFileHealthCheck", string(raw))
5757

5858
var tests DefTests
5959
err = json.Unmarshal([]byte(raw), &tests)
@@ -131,7 +131,7 @@ func HealthCheckHandler(w http.ResponseWriter, r *http.Request, srcpath string)
131131
fmt.Fprintf(w, `{ "err": %q }`, err.Error())
132132
return
133133
}
134-
log.Info(string(jsonRes))
134+
log.Debug(string(jsonRes))
135135
err = ioutil.WriteFile(hcResFp, jsonRes, 0644)
136136
CheckError(err)
137137
}

webapp/lib/sciond.go

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7+
"errors"
78
"fmt"
9+
"io"
810
"io/ioutil"
911
"net/http"
12+
"os"
1013
"path"
1114
"path/filepath"
1215
"runtime"
1316
"strconv"
1417
"strings"
1518

1619
log "github.com/inconshreveable/log15"
20+
pathdb "github.com/netsec-ethz/scion-apps/webapp/models/path"
1721
. "github.com/netsec-ethz/scion-apps/webapp/util"
1822
"github.com/scionproto/scion/go/lib/addr"
1923
"github.com/scionproto/scion/go/lib/common"
@@ -46,6 +50,11 @@ func PathTopoHandler(w http.ResponseWriter, r *http.Request) {
4650
SPort, _ := strconv.Atoi(r.PostFormValue("port_ser"))
4751
CPort, _ := strconv.Atoi(r.PostFormValue("port_cli"))
4852

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+
}
4958
optClient := fmt.Sprintf("%s,[%s]:%d", CIa, CAddr, CPort)
5059
optServer := fmt.Sprintf("%s,[%s]:%d", SIa, SAddr, SPort)
5160
clientCCAddr, _ := snet.AddrFromString(optClient)
@@ -79,7 +88,74 @@ func PathTopoHandler(w http.ResponseWriter, r *http.Request) {
7988
jsonPathInfo, _ := json.Marshal(paths)
8089
log.Debug("PathTopoHandler:", "jsonPathInfo", string(jsonPathInfo))
8190

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)
83159
}
84160

85161
func getPaths(local snet.Addr, remote snet.Addr) []*spathmeta.AppPath {

webapp/models/db.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func LoadDB() {
4545
addColumn("bwtests", "Log TEXT")
4646
}
4747
//set updated version
48-
if version != bwDbVer {
48+
if version < bwDbVer {
4949
setUserVersion(bwDbVer)
5050
log.Info("Migrated to database version", "version", bwDbVer)
5151
}

webapp/models/path/db.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package pathdb
2+
3+
import (
4+
"database/sql"
5+
6+
. "github.com/netsec-ethz/scion-apps/webapp/util"
7+
)
8+
9+
func InitDB(filepath string) *sql.DB {
10+
var err error
11+
db, err := sql.Open("sqlite3", filepath+"?mode=ro")
12+
if CheckError(err) {
13+
panic(err)
14+
}
15+
err = db.Ping()
16+
if CheckError(err) {
17+
panic(err)
18+
}
19+
return db
20+
}
21+
22+
func CloseDB(db *sql.DB) {
23+
err := db.Close()
24+
if CheckError(err) {
25+
panic(err)
26+
}
27+
}

webapp/models/path/segments.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package pathdb
2+
3+
import (
4+
"database/sql"
5+
"time"
6+
7+
. "github.com/netsec-ethz/scion-apps/webapp/util"
8+
"github.com/scionproto/scion/go/lib/addr"
9+
"github.com/scionproto/scion/go/lib/common"
10+
"github.com/scionproto/scion/go/lib/ctrl/seg"
11+
"github.com/scionproto/scion/go/proto"
12+
)
13+
14+
type asIface struct {
15+
IA addr.IA
16+
IfNum common.IFIDType
17+
}
18+
19+
func newASIface(isd addr.ISD, as addr.AS, ifNum common.IFIDType) asIface {
20+
return asIface{IA: addr.IA{I: isd, A: as}, IfNum: ifNum}
21+
}
22+
23+
type segment struct {
24+
SegType string
25+
Src addr.IA
26+
Dst addr.IA
27+
Interfaces []asIface
28+
Updated time.Time
29+
Expiry time.Time
30+
}
31+
32+
func newSegment(segType proto.PathSegType, srcI addr.ISD, srcA addr.AS, dstI addr.ISD, dstA addr.AS,
33+
packedSeg []byte, updateTime, expiryTime int64) segment {
34+
35+
// traverse the segments to ensure even number of inferfaces in hops
36+
var err error
37+
var theseg *seg.PathSegment
38+
theseg, err = seg.NewSegFromRaw(common.RawBytes(packedSeg))
39+
if CheckError(err) {
40+
panic(err)
41+
}
42+
var interfaces []asIface
43+
for _, ase := range theseg.ASEntries {
44+
hop, err := ase.HopEntries[0].HopField()
45+
if CheckError(err) {
46+
panic(err)
47+
}
48+
if hop.ConsIngress > 0 {
49+
interfaces = append(interfaces, newASIface(ase.IA().I, ase.IA().A, hop.ConsIngress))
50+
}
51+
if hop.ConsEgress > 0 {
52+
interfaces = append(interfaces, newASIface(ase.IA().I, ase.IA().A, hop.ConsEgress))
53+
}
54+
}
55+
return segment{SegType: segType.String(), Src: addr.IA{I: srcI, A: srcA}, Dst: addr.IA{I: dstI, A: dstA},
56+
Interfaces: interfaces, Updated: time.Unix(0, updateTime), Expiry: time.Unix(expiryTime, 0)}
57+
}
58+
59+
func ReadSegTypesAll(db *sql.DB) map[int64]proto.PathSegType {
60+
sqlReadAll := `
61+
SELECT
62+
SegRowID,
63+
Type
64+
FROM SegTypes
65+
`
66+
rows, err := db.Query(sqlReadAll)
67+
if CheckError(err) {
68+
panic(err)
69+
}
70+
defer rows.Close()
71+
72+
var segRowID int64
73+
var segType proto.PathSegType
74+
var result = map[int64]proto.PathSegType{}
75+
for rows.Next() {
76+
err = rows.Scan(
77+
&segRowID,
78+
&segType)
79+
if CheckError(err) {
80+
panic(err)
81+
}
82+
result[segRowID] = segType
83+
}
84+
return result
85+
}
86+
87+
func ReadIntfToSegAll(db *sql.DB) map[int64][]asIface {
88+
sqlReadAll := `
89+
SELECT
90+
IsdID,
91+
AsID,
92+
IntfID,
93+
SegRowID
94+
FROM IntfToSeg
95+
`
96+
rows, err := db.Query(sqlReadAll)
97+
if CheckError(err) {
98+
panic(err)
99+
}
100+
defer rows.Close()
101+
102+
var segRowID int64
103+
var isd addr.ISD
104+
var as addr.AS
105+
var ifaceID common.IFIDType
106+
var result = map[int64][]asIface{}
107+
for rows.Next() {
108+
err = rows.Scan(
109+
&isd,
110+
&as,
111+
&ifaceID,
112+
&segRowID)
113+
if CheckError(err) {
114+
panic(err)
115+
}
116+
result[segRowID] = append(result[segRowID], newASIface(isd, as, ifaceID))
117+
}
118+
return result
119+
}
120+
121+
func ReadSegmentsAll(db *sql.DB, segTypes map[int64]proto.PathSegType) []segment {
122+
sqlReadAll := `
123+
SELECT
124+
RowID,
125+
LastUpdated,
126+
Segment,
127+
MaxExpiry,
128+
StartIsdID,
129+
StartAsID,
130+
EndIsdID,
131+
EndAsID
132+
FROM Segments
133+
`
134+
rows, err := db.Query(sqlReadAll)
135+
if CheckError(err) {
136+
panic(err)
137+
}
138+
defer rows.Close()
139+
140+
var segRowID int64
141+
var packedSeg []byte
142+
var lastUpdated, maxExpiry int64
143+
var startISD, endISD addr.ISD
144+
var startAS, endAS addr.AS
145+
var result = []segment{}
146+
for rows.Next() {
147+
err = rows.Scan(
148+
&segRowID,
149+
&lastUpdated,
150+
&packedSeg,
151+
&maxExpiry,
152+
&startISD,
153+
&startAS,
154+
&endISD,
155+
&endAS)
156+
if CheckError(err) {
157+
panic(err)
158+
}
159+
segmt := newSegment(segTypes[segRowID], startISD, startAS, endISD, endAS, packedSeg, lastUpdated, maxExpiry)
160+
result = append(result, segmt)
161+
}
162+
return result
163+
}

0 commit comments

Comments
 (0)