Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FABRID bw-tester with validation at destination #258

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions bwtester/bwtestclient/bwtestclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"time"
"unicode"

"github.com/scionproto/scion/private/path/fabridquery"

"github.com/netsec-ethz/scion-apps/bwtester/bwtest"
"github.com/netsec-ethz/scion-apps/pkg/pan"
)
Expand Down Expand Up @@ -267,6 +269,7 @@ func main() {
interactive bool
sequence string
preference string
fabridQuery string
)

flag.Usage = printUsage
Expand All @@ -279,6 +282,7 @@ func main() {
flag.StringVar(&preference, "preference", "", "Preference sorting order for paths. "+
"Comma-separated list of available sorting options: "+
strings.Join(pan.AvailablePreferencePolicies, "|"))
flag.StringVar(&fabridQuery, "fabridquery", "", "Query for FABRID policies")

flag.Parse()
flagset := make(map[string]bool)
Expand Down Expand Up @@ -320,7 +324,7 @@ func main() {
fmt.Printf("server->client: %d seconds, %d bytes, %d packets\n",
int(serverBwp.BwtestDuration/time.Second), serverBwp.PacketSize, serverBwp.NumPackets)

clientRes, serverRes, err := runBwtest(local.Get(), serverCCAddr, policy, clientBwp, serverBwp)
clientRes, serverRes, err := runBwtest(local.Get(), serverCCAddr, policy, clientBwp, serverBwp, fabridQuery)
bwtest.Check(err)

fmt.Println("\nS->C results")
Expand All @@ -330,8 +334,7 @@ func main() {
}

// runBwtest runs the bandwidth test with the given parameters against the server at serverCCAddr.
func runBwtest(local netip.AddrPort, serverCCAddr pan.UDPAddr, policy pan.Policy,
clientBwp, serverBwp bwtest.Parameters) (clientRes, serverRes bwtest.Result, err error) {
func runBwtest(local netip.AddrPort, serverCCAddr pan.UDPAddr, policy pan.Policy, clientBwp, serverBwp bwtest.Parameters, fabridQuery string) (clientRes, serverRes bwtest.Result, err error) {

// Control channel connection
ccSelector := pan.NewDefaultSelector()
Expand All @@ -345,7 +348,16 @@ func runBwtest(local netip.AddrPort, serverCCAddr pan.UDPAddr, policy pan.Policy
serverDCAddr := serverCCAddr.WithPort(serverCCAddr.Port + 1)

// Data channel connection
dcConn, err := pan.DialUDP(context.Background(), dcLocal, serverDCAddr, policy, nil)
var selector pan.Selector
if fabridQuery != "" {
query, err := fabridquery.ParseFabridQuery(fabridQuery)
if err != nil {
return bwtest.Result{}, bwtest.Result{}, err
}
selector = pan.NewFabridSelector(query, context.Background())
}

dcConn, err := pan.DialUDP(context.Background(), dcLocal, serverDCAddr, policy, selector)
if err != nil {
return
}
Expand Down
23 changes: 16 additions & 7 deletions bwtester/bwtestserver/bwtestserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ const (
func main() {
var listen pan.IPPortValue
kingpin.Flag("listen", "Address to listen on").Default(":40002").SetValue(&listen)
fabrid := kingpin.Flag("fabrid", "Enable FABRID").Bool()
kingpin.Parse()

err := runServer(listen.Get())
err := runServer(listen.Get(), *fabrid)
bwtest.Check(err)
}

func runServer(listen netip.AddrPort) error {
func runServer(listen netip.AddrPort, enableFabrid bool) error {
receivePacketBuffer := make([]byte, 2500)

var currentBwtest string
Expand All @@ -57,6 +58,7 @@ func runServer(listen netip.AddrPort) error {
return err
}
serverCCAddr := ccConn.LocalAddr().(pan.UDPAddr)
fmt.Println("Server listening on ", serverCCAddr, " fabrid:", enableFabrid)
for {
// Handle client requests
n, clientCCAddr, err := ccConn.ReadFrom(receivePacketBuffer)
Expand Down Expand Up @@ -103,7 +105,7 @@ func runServer(listen netip.AddrPort) error {
}
path := ccSelector.Path(clientCCAddr.(pan.UDPAddr))
finishTime, err := startBwtestBackground(serverCCAddr, clientCCAddr.(pan.UDPAddr), path,
clientBwp, serverBwp, currentResult)
clientBwp, serverBwp, currentResult, enableFabrid)
if err != nil {
// Ask the client to try again in 1 second
writeResponseN(ccConn, clientCCAddr, 1)
Expand Down Expand Up @@ -134,7 +136,7 @@ func runServer(listen netip.AddrPort) error {
// startBwtestBackground starts a bandwidth test, in the background.
// Returns the expected finish time of the test, or any error during the setup.
func startBwtestBackground(serverCCAddr pan.UDPAddr, clientCCAddr pan.UDPAddr,
path *pan.Path, clientBwp, serverBwp bwtest.Parameters, res chan<- bwtest.Result) (time.Time, error) {
path *pan.Path, clientBwp, serverBwp bwtest.Parameters, res chan<- bwtest.Result, enableFabrid bool) (time.Time, error) {

// Data Connection addresses:
clientDCAddr := clientCCAddr
Expand All @@ -143,7 +145,7 @@ func startBwtestBackground(serverCCAddr pan.UDPAddr, clientCCAddr pan.UDPAddr,

// Open Data Connection
dcSelector := initializedReplySelector(clientDCAddr, path)
dcConn, err := listenConnected(serverDCAddr, clientDCAddr, dcSelector)
dcConn, err := listenConnected(serverDCAddr, clientDCAddr, dcSelector, enableFabrid)
if err != nil {
return time.Time{}, err
}
Expand Down Expand Up @@ -286,8 +288,15 @@ func (r resultsMap) purgeExpired() {
}
}

func listenConnected(local netip.AddrPort, remote pan.UDPAddr, selector pan.ReplySelector) (net.Conn, error) {
conn, err := pan.ListenUDP(context.Background(), local, selector)
func listenConnected(local netip.AddrPort, remote pan.UDPAddr, selector pan.ReplySelector, enableFabrid bool) (net.Conn, error) {
var err error
var conn pan.ListenConn
if enableFabrid {
conn, err = pan.ListenUDPWithFabrid(context.Background(), local, remote, selector)

} else {
conn, err = pan.ListenUDP(context.Background(), local, selector)
}
return connectedPacketConn{
ListenConn: conn,
remote: remote,
Expand Down
86 changes: 86 additions & 0 deletions pkg/pan/fabrid_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2021 ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pan

import (
"context"
"fmt"
"time"

"github.com/scionproto/scion/pkg/addr"
"github.com/scionproto/scion/pkg/drkey"
"github.com/scionproto/scion/pkg/experimental/fabrid/crypto"
"github.com/scionproto/scion/pkg/private/serrors"
"github.com/scionproto/scion/pkg/slayers/extension"
)

type FabridServer struct {
Local UDPAddr
Source UDPAddr
tmpBuffer []byte
pathKey *drkey.HostHostKey
ctx context.Context
}

func NewFabridServer(ctx context.Context, local UDPAddr, remote UDPAddr) *FabridServer {
server := &FabridServer{
Local: local,
Source: remote,
tmpBuffer: make([]byte, 192),
ctx: ctx,
}
err := server.refreshPathKey(time.Now())
if err != nil {
fmt.Println("Failed to fetch path key. Does your local IP differ from your SD?\nError:", err)
return nil
}
return server
}

func (s *FabridServer) refreshPathKey(validity time.Time) error {
if s.pathKey == nil || !s.pathKey.Epoch.Contains(validity) {
meta := drkey.HostHostMeta{
Validity: validity,
SrcIA: addr.IA(s.Local.IA),
SrcHost: s.Local.IP.String(),
DstIA: addr.IA(s.Source.IA),
DstHost: s.Source.IP.String(),
ProtoId: drkey.FABRID,
}
hostHostKey, err := host().drkeyGetHostHostKey(s.ctx, meta)
if err != nil {
return serrors.WrapStr("getting host key", err)
}
s.pathKey = &hostHostKey

}
return nil
}

func (s *FabridServer) HandleFabridPacket(fabridOption *extension.FabridOption,
identifierOption *extension.IdentifierOption) error {
err := s.refreshPathKey(identifierOption.Timestamp)
if err != nil {
fmt.Println("Failed to fetch path key. Does your local IP differ from your SD?\nError:", err)
return err
}
_, err = crypto.VerifyPathValidator(fabridOption,
s.tmpBuffer, s.pathKey.Key[:])
if err != nil {
fmt.Println("Failed to verify FABRID packet. Error:", err)
return err
}
return nil
}
5 changes: 5 additions & 0 deletions pkg/pan/path_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,14 @@ type PathMetadata struct {
// Notes contains the notes added by ASes on the path, in the order of occurrence.
// Entry i is the note of AS i on the path.
Notes []string

// FabridInfo contains information about the FABRID policies and support for each hop.
FabridInfo []FabridInfo
}

type GeoCoordinates = snet.GeoCoordinates
type LinkType = snet.LinkType
type FabridInfo = snet.FabridInfo

func (pm *PathMetadata) Copy() *PathMetadata {
if pm == nil {
Expand All @@ -93,6 +97,7 @@ func (pm *PathMetadata) Copy() *PathMetadata {
LinkType: append(pm.LinkType[:0:0], pm.LinkType...),
InternalHops: append(pm.InternalHops[:0:0], pm.InternalHops...),
Notes: append(pm.Notes[:0:0], pm.Notes...),
FabridInfo: append(pm.FabridInfo[:0:0], pm.FabridInfo...),
}
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/pan/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (c *baseUDPConn) writeMsg(src, dst UDPAddr, path *Path, b []byte) (int, err
// readMsg is a helper for reading a single packet.
// Internally invokes the configured SCMP handler.
// Ignores non-UDP packets.
func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, error) {
func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, *slayers.HopByHopExtn, *slayers.EndToEndExtn, error) {
c.readMutex.Lock()
defer c.readMutex.Unlock()
if c.readBuffer == nil {
Expand All @@ -124,7 +124,7 @@ func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, error) {
var lastHop net.UDPAddr
err := c.raw.ReadFrom(&pkt, &lastHop)
if err != nil {
return 0, UDPAddr{}, ForwardingPath{}, err
return 0, UDPAddr{}, ForwardingPath{}, nil, nil, err
}
udp, ok := pkt.Payload.(snet.UDPPayload)
if !ok {
Expand All @@ -144,7 +144,7 @@ func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, error) {
underlay: underlay,
}
n := copy(b, udp.Payload)
return n, remote, fw, nil
return n, remote, fw, pkt.HbhExtension, pkt.E2eExtension, nil
}
}

Expand Down
10 changes: 10 additions & 0 deletions pkg/pan/sciond.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/scionproto/scion/pkg/addr"
"github.com/scionproto/scion/pkg/daemon"
"github.com/scionproto/scion/pkg/drkey"
"github.com/scionproto/scion/pkg/snet"
"github.com/scionproto/scion/pkg/snet/addrutil"
)
Expand Down Expand Up @@ -146,6 +147,7 @@ func (h *hostContext) queryPaths(ctx context.Context, dst IA) ([]*Path, error) {
LinkType: snetMetadata.LinkType,
InternalHops: snetMetadata.InternalHops,
Notes: snetMetadata.Notes,
FabridInfo: snetMetadata.FabridInfo,
}
underlay := p.UnderlayNextHop().AddrPort()
paths[i] = &Path{
Expand All @@ -163,6 +165,14 @@ func (h *hostContext) queryPaths(ctx context.Context, dst IA) ([]*Path, error) {
return paths, nil
}

func (h *hostContext) drkeyGetHostHostKey(ctx context.Context, meta drkey.HostHostMeta) (drkey.HostHostKey, error) {
return h.sciond.DRKeyGetHostHostKey(ctx, meta)
}

func (h *hostContext) fabridKeys() func(ctx context.Context, meta drkey.FabridKeysMeta) (drkey.FabridKeysResponse, error) {
return h.sciond.FabridKeys
}

func convertPathInterfaceSlice(spis []snet.PathInterface) []PathInterface {
pis := make([]PathInterface, len(spis))
for i, spi := range spis {
Expand Down
Loading