envelope.go raw

   1  package tunnel
   2  
   3  import (
   4  	"encoding/json"
   5  	"errors"
   6  	"fmt"
   7  )
   8  
   9  // Frame types carried inside the NIP-44 payload. The outer event kind only
  10  // says which direction a frame travels; the type inside the ciphertext is
  11  // authoritative, and is checked against the direction.
  12  const (
  13  	frameHello    = "hello"
  14  	frameHelloAck = "hello_ack"
  15  	frameData     = "data"
  16  	frameAck      = "ack"
  17  	frameNack     = "nack"
  18  	framePing     = "ping"
  19  	framePong     = "pong"
  20  	frameClose    = "close"
  21  	frameReset    = "reset"
  22  )
  23  
  24  // envelope is the plaintext of one tunnel event.
  25  type envelope struct {
  26  	V      int      `json:"v"`
  27  	S      string   `json:"s"`
  28  	T      string   `json:"t"`
  29  	Seq    uint32   `json:"q,omitempty"`
  30  	Ack    uint32   `json:"a,omitempty"`
  31  	Data   []byte   `json:"d,omitempty"`
  32  	Nack   []uint32 `json:"x,omitempty"`
  33  	MTU    int      `json:"m,omitempty"`
  34  	Win    int      `json:"w,omitempty"`
  35  	PV     int      `json:"pv,omitempty"`
  36  	Chain  string   `json:"c,omitempty"`
  37  	Nonce  uint64   `json:"n,omitempty"`
  38  	Reason string   `json:"r,omitempty"`
  39  }
  40  
  41  func (e *envelope) marshal() ([]byte, error) {
  42  	b, err := json.Marshal(e)
  43  	if err != nil {
  44  		return nil, fmt.Errorf("tunnel: encode envelope: %w", err)
  45  	}
  46  	return b, nil
  47  }
  48  
  49  func parseEnvelope(raw []byte) (*envelope, error) {
  50  	var e envelope
  51  	if err := json.Unmarshal(raw, &e); err != nil {
  52  		return nil, fmt.Errorf("tunnel: decode envelope: %w", err)
  53  	}
  54  	if e.V != protocolVersion {
  55  		return nil, fmt.Errorf("tunnel: unsupported envelope version %d", e.V)
  56  	}
  57  	if e.S == "" {
  58  		return nil, errors.New("tunnel: envelope has no session")
  59  	}
  60  	return &e, nil
  61  }
  62