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

properly send ohp packet for header v2 #3826

Merged
merged 1 commit into from
Jul 10, 2020
Merged
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
13 changes: 13 additions & 0 deletions go/cs/onehop/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ type Sender struct {
macMtx sync.Mutex
// MAC is the mac to issue hop fields.
MAC hash.Hash
// HeaderV2 indicates the new header format should be used.
HeaderV2 bool
}

// Send sends the payload on a one-hop path.
Expand Down Expand Up @@ -99,13 +101,24 @@ func (s *Sender) CreatePkt(msg *Msg) (*snet.Packet, error) {
Payload: msg.Pld,
},
}
// For v2 we don't need the OHP extension.
if s.HeaderV2 {
pkt.PacketInfo.Extensions = nil
}
return pkt, nil
}

// CreatePath creates the one-hop path and initializes it.
func (s *Sender) CreatePath(ifid common.IFIDType, now time.Time) (*Path, error) {
s.macMtx.Lock()
defer s.macMtx.Unlock()
if s.HeaderV2 {
path, err := spath.NewOneHopV2(s.IA.I, ifid, now, spath.DefaultHopFExpiry, s.MAC)
if err != nil {
return nil, err
}
return (*Path)(path), nil
}
path := spath.NewOneHop(s.IA.I, ifid, now, spath.DefaultHopFExpiry, s.MAC)
return (*Path)(path), path.InitOffsets()
}
Expand Down
1 change: 0 additions & 1 deletion go/lib/hpkt/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ go_library(
"//go/lib/scmp:go_default_library",
"//go/lib/serrors:go_default_library",
"//go/lib/slayers:go_default_library",
"//go/lib/slayers/path:go_default_library",
"//go/lib/slayers/path/onehop:go_default_library",
"//go/lib/slayers/path/scion:go_default_library",
"//go/lib/spath:go_default_library",
Expand Down
86 changes: 22 additions & 64 deletions go/lib/hpkt/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ import (
"github.com/scionproto/scion/go/lib/scmp"
"github.com/scionproto/scion/go/lib/serrors"
"github.com/scionproto/scion/go/lib/slayers"
"github.com/scionproto/scion/go/lib/slayers/path"
"github.com/scionproto/scion/go/lib/slayers/path/onehop"
"github.com/scionproto/scion/go/lib/slayers/path/scion"
"github.com/scionproto/scion/go/lib/spath"
"github.com/scionproto/scion/go/lib/spkt"
"github.com/scionproto/scion/go/lib/util"
)
Expand Down Expand Up @@ -223,74 +221,34 @@ func WriteScnPkt2(s *spkt.ScnPkt, b []byte) (int, error) {
}
scionLayer.PathType = slayers.PathTypeSCION

isOneHop := func() bool {
if len(s.HBHExt) != 0 {
_, ok := s.HBHExt[0].(*deprecatedlayers.ExtnOHP)
return ok
switch {
case s.Path == nil:
// Default nil paths to an empty SCION path
decodedPath := scion.Decoded{
Base: scion.Base{
PathMeta: scion.MetaHdr{},
},
}
return false
}
if isOneHop() {
if !s.Path.IsHeaderV2() {
info, err := s.Path.GetInfoField(0)
if err != nil {
return 0, serrors.WrapStr("extracing one hop info field", err)
}
hf, err := s.Path.GetHopField(spath.InfoFieldLength)
if err != nil {
return 0, serrors.WrapStr("extracting one hop hop field", err)
}
scionLayer.PathType = slayers.PathTypeOneHop
scionLayer.Path = &onehop.Path{
Info: path.InfoField{
ConsDir: true,
Timestamp: info.TsInt,
},
FirstHop: path.HopField{
ConsEgress: uint16(hf.ConsEgress),
ExpTime: uint8(hf.ExpTime),
},
}
} else {
var path onehop.Path
if err := path.DecodeFromBytes(s.Path.Raw); err != nil {
return 0, serrors.WrapStr("decoding path", err)
}
scionLayer.PathType = slayers.PathTypeOneHop
scionLayer.Path = &path
scionLayer.Path = &decodedPath
case s.Path.IsHeaderV2() && s.Path.IsOHP():
var path onehop.Path
if err := path.DecodeFromBytes(s.Path.Raw); err != nil {
return 0, serrors.WrapStr("decoding path", err)
}
} else {
switch {
case s.Path == nil:
// Default nil paths to an empty SCION path
decodedPath := scion.Decoded{
Base: scion.Base{
PathMeta: scion.MetaHdr{},
},
}
scionLayer.Path = &decodedPath
case s.Path.IsHeaderV2() && s.Path.IsOHP():
var path onehop.Path
if err := path.DecodeFromBytes(s.Path.Raw); err != nil {
return 0, serrors.WrapStr("decoding path", err)
}
scionLayer.PathType = slayers.PathTypeOneHop
scionLayer.Path = &path
default:
// Use decoded for simplicity, easier to work with when debugging with delve.
var decodedPath scion.Decoded
if err := decodedPath.DecodeFromBytes(s.Path.Raw); err != nil {
return 0, serrors.WrapStr("decoding path", err)
}
scionLayer.Path = &decodedPath
scionLayer.PathType = slayers.PathTypeOneHop
scionLayer.Path = &path
default:
// Use decoded for simplicity, easier to work with when debugging with delve.
var decodedPath scion.Decoded
if err := decodedPath.DecodeFromBytes(s.Path.Raw); err != nil {
return 0, serrors.WrapStr("decoding path", err)
}
scionLayer.Path = &decodedPath
}
packetLayers = append(packetLayers, &scionLayer)

// XXX(scrye): No extensions are defined for the V2 header format. However,
// application code uses some V1 extensions like the One-Hop Path, and these
// will need to be converted for V2 to the new One-Hop path type.
if len(s.HBHExt) != 0 && !isOneHop() {
// XXX(scrye): No extensions are defined for the V2 header format.
if len(s.HBHExt) != 0 {
return 0, serrors.New("HBH extensions are not supported for Header V2")
}
if len(s.E2EExt) != 0 {
Expand Down
1 change: 1 addition & 0 deletions go/lib/spath/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ go_library(
"//go/lib/addr:go_default_library",
"//go/lib/common:go_default_library",
"//go/lib/serrors:go_default_library",
"//go/lib/slayers/path:go_default_library",
"//go/lib/slayers/path/onehop:go_default_library",
"//go/lib/slayers/path/scion:go_default_library",
"//go/lib/util:go_default_library",
Expand Down
47 changes: 47 additions & 0 deletions go/lib/spath/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
package spath

import (
"crypto/rand"
"encoding/binary"
"fmt"
"hash"
"math"
"math/big"
"time"

"github.com/scionproto/scion/go/lib/addr"
"github.com/scionproto/scion/go/lib/common"
"github.com/scionproto/scion/go/lib/serrors"
"github.com/scionproto/scion/go/lib/slayers/path"
"github.com/scionproto/scion/go/lib/slayers/path/onehop"
"github.com/scionproto/scion/go/lib/slayers/path/scion"
"github.com/scionproto/scion/go/lib/util"
Expand Down Expand Up @@ -79,6 +83,49 @@ func NewOneHop(isd addr.ISD, ifid common.IFIDType, ts time.Time, exp ExpTimeType
return New(raw)
}

func NewOneHopV2(isd addr.ISD, ifid common.IFIDType, ts time.Time, exp ExpTimeType,
hfmac hash.Hash) (*Path, error) {

segID, err := rand.Int(rand.Reader, big.NewInt(1<<16))
if err != nil {
return nil, err
}
ohp := onehop.Path{
Info: path.InfoField{
ConsDir: true,
Timestamp: util.TimeToSecs(ts),
SegID: uint16(segID.Uint64()),
},
FirstHop: path.HopField{
ConsEgress: uint16(ifid),
ExpTime: uint8(exp),
},
}

input := make([]byte, 16)
binary.BigEndian.PutUint32(input[:4], util.TimeToSecs(ts))
input[4] = uint8(exp)
binary.BigEndian.PutUint16(input[7:9], ohp.FirstHop.ConsEgress)
binary.BigEndian.PutUint16(input[9:11], ohp.Info.SegID)

// Write must not return an error: https://godoc.org/hash#Hash
if _, err := hfmac.Write(input); err != nil {
panic(err)
}
fullMAC := hfmac.Sum(nil)
ohp.FirstHop.Mac = fullMAC[:6]

raw := make([]byte, onehop.PathLen)
if err := ohp.SerializeTo(raw); err != nil {
return nil, err
}
return &Path{
Raw: raw,
version: 2,
ohp: true,
}, nil
}

func (p *Path) Copy() *Path {
if p == nil {
return nil
Expand Down
27 changes: 15 additions & 12 deletions go/pkg/cs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -677,10 +677,11 @@ func (t *PeriodicTasks) startRevoker() (*periodic.Runner, error) {
func (t *PeriodicTasks) StartKeepaliveSender(a *net.UDPAddr) (*periodic.Runner, error) {
s := &keepalive.Sender{
Sender: &onehop.Sender{
Conn: t.conn,
IA: t.TopoProvider.Get().IA(),
MAC: t.genMac(),
Addr: a,
Conn: t.conn,
IA: t.TopoProvider.Get().IA(),
MAC: t.genMac(),
Addr: a,
HeaderV2: t.headerV2,
},
Signer: infra.NullSigner,
TopoProvider: t.TopoProvider,
Expand All @@ -698,10 +699,11 @@ func (t *PeriodicTasks) startOriginator(a *net.UDPAddr) (*periodic.Runner, error
Extender: t.extender("propagator", topo, maxExpTimeFactory(t.store, beacon.PropPolicy)),
BeaconSender: &onehop.BeaconSender{
Sender: onehop.Sender{
Conn: t.conn,
IA: topo.IA(),
MAC: t.genMac(),
Addr: a,
Conn: t.conn,
IA: topo.IA(),
MAC: t.genMac(),
Addr: a,
HeaderV2: t.headerV2,
},
AddressRewriter: t.addressRewriter,
QUICBeaconSender: t.msgr,
Expand All @@ -720,10 +722,11 @@ func (t *PeriodicTasks) startPropagator(a *net.UDPAddr) (*periodic.Runner, error
Extender: t.extender("propagator", topo, maxExpTimeFactory(t.store, beacon.PropPolicy)),
BeaconSender: &onehop.BeaconSender{
Sender: onehop.Sender{
Conn: t.conn,
IA: topo.IA(),
MAC: t.genMac(),
Addr: a,
Conn: t.conn,
IA: topo.IA(),
MAC: t.genMac(),
Addr: a,
HeaderV2: t.headerV2,
},
AddressRewriter: t.addressRewriter,
QUICBeaconSender: t.msgr,
Expand Down