From c7da9212cd18c06313fbf087205a93c06d8cacee Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Tue, 10 Jul 2018 00:45:11 -0700 Subject: [PATCH] Add comments to SCTP + start InitAck --- internal/network/port-receive.go | 3 +-- internal/sctp/association.go | 9 ++++++++ internal/sctp/chunk_init.go | 17 +-------------- internal/sctp/chunk_init_ack.go | 36 +++++++++++++++++++++++--------- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/internal/network/port-receive.go b/internal/network/port-receive.go index 08c1d0b6..242eb7ae 100644 --- a/internal/network/port-receive.go +++ b/internal/network/port-receive.go @@ -213,9 +213,8 @@ func (p *Port) networkLoop(remoteKey []byte, tlscfg *dtls.TLSCfg, b BufferTransp p.sctpAssocations[in.srcAddr.String()] = sctp.NewAssocation(func(pkt *sctp.Packet) { fmt.Printf("Handle packet %v \n", pkt) }, func(data []byte) { - + fmt.Printf("Handle data %v \n", data) }) - } } } diff --git a/internal/sctp/association.go b/internal/sctp/association.go index e459277f..d5330cf5 100644 --- a/internal/sctp/association.go +++ b/internal/sctp/association.go @@ -25,6 +25,8 @@ const ( func (a AssociationState) String() string { switch a { + case Open: + return "Open" case CookieEchoed: return "CookieEchoed" case CookieWait: @@ -70,6 +72,8 @@ type Association struct { myMaxNumInboundStreams uint16 myMaxNumOutboundStreams uint16 + // TODO are these better as channels + // Put a blocking goroutine in port-recieve (vs callbacks) outboundHandler func(*Packet) dataHandler func([]byte) } @@ -143,6 +147,11 @@ func (a *Association) handleChunk(c Chunk) error { a.myMaxNumInboundStreams = min(ct.numInboundStreams, a.myMaxNumInboundStreams) a.myMaxNumOutboundStreams = min(ct.numOutboundStreams, a.myMaxNumOutboundStreams) a.State = CookieEchoed + + // TODO send packet attributes + append InitAck + // We should also cache the InitAck to handle CookieEchoed when we get Init + outbound := &Packet{} + a.outboundHandler(outbound) case CookieEchoed: // https://tools.ietf.org/html/rfc4960#section-5.2.1 // Upon receipt of an INIT in the COOKIE-ECHOED state, an endpoint MUST diff --git a/internal/sctp/chunk_init.go b/internal/sctp/chunk_init.go index b68235da..db50450c 100644 --- a/internal/sctp/chunk_init.go +++ b/internal/sctp/chunk_init.go @@ -128,22 +128,6 @@ func (i *Init) Unmarshal(raw []byte) error { break } } - - // TODO Sean-Der - // offset := initChunkMinLength - // for { - // remaining := len(i.Value) - offset - // if remaining == 0 { - // break - // } else if remaining < initOptionalVarHeaderLength { - // return errors.Errorf("%d bytes remain in init chunk value, not enough to build optional var header", remaining) - // } - - // attributeType := binary.BigEndian.Uint16(i.Value[offset:]) - // attributeLength := int(binary.BigEndian.Uint16(i.Value[offset+2:])) - - // offset += attributeLength - // } return nil } @@ -152,6 +136,7 @@ func (i *Init) Marshal() ([]byte, error) { return nil, errors.Errorf("Unimplemented") } +// Check asserts the validity of this structs values func (i *Init) Check() error { // Defines the maximum number of streams the sender of this INIT // chunk allows the peer end to create in this association. The diff --git a/internal/sctp/chunk_init_ack.go b/internal/sctp/chunk_init_ack.go index e9ee74d7..1104b064 100644 --- a/internal/sctp/chunk_init_ack.go +++ b/internal/sctp/chunk_init_ack.go @@ -1,6 +1,10 @@ package sctp -import "github.com/pkg/errors" +import ( + "encoding/binary" + + "github.com/pkg/errors" +) /* InitAck represents an SCTP Chunk of type INIT ACK @@ -47,17 +51,16 @@ Host Name Address (Note 3) Optional 11 */ type InitAck struct { ChunkHeader - // initiateTag uint32 - // advertisedReceiverWindowCredit uint32 - // numOutboundStreams uint16 - // numInboundStreams uint16 - // initialTSN uint32 - // optionalParams []byte + initiateTag uint32 + advertisedReceiverWindowCredit uint32 + numOutboundStreams uint16 + numInboundStreams uint16 + initialTSN uint32 + params []Param } const ( -// initAckChunkMinLength = 16 -// initAckOptionalVarHeaderLength = 4 + initAckChunkMinLength = 16 ) // Unmarshal populates a InitAck Chunk from a byte slice @@ -67,5 +70,18 @@ func (i *InitAck) Unmarshal(raw []byte) error { // Marshal serializes a InitAck to bytes func (i *InitAck) Marshal() ([]byte, error) { - return nil, errors.Errorf("Unimplemented") + out := make([]byte, initAckChunkMinLength) + binary.BigEndian.PutUint32(out[0:], i.initiateTag) + binary.BigEndian.PutUint32(out[4:], i.advertisedReceiverWindowCredit) + binary.BigEndian.PutUint16(out[8:], i.numOutboundStreams) + binary.BigEndian.PutUint16(out[10:], i.numInboundStreams) + binary.BigEndian.PutUint32(out[12:], i.initialTSN) + + // TODO fill in params + return out, nil +} + +// Check asserts the validity of this structs values +func (i *InitAck) Check() error { + return nil }