1
0

connection_state.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package nebula
  2. import (
  3. "encoding/json"
  4. "sync"
  5. "sync/atomic"
  6. "github.com/slackhq/nebula/cert"
  7. "github.com/slackhq/nebula/handshake"
  8. "github.com/slackhq/nebula/noiseutil"
  9. )
  10. const ReplayWindow = 8192
  11. type ConnectionState struct {
  12. eKey noiseutil.CipherState
  13. dKey noiseutil.CipherState
  14. myCert cert.Certificate
  15. peerCert *cert.CachedCertificate
  16. initiator bool
  17. messageCounter atomic.Uint64
  18. window *Bits
  19. writeLock sync.Mutex
  20. }
  21. // newConnectionStateFromResult builds a fully-populated ConnectionState from a
  22. // completed handshake.Result. It seeds messageCounter and the replay window so
  23. // that the post-handshake message indices already used on the wire don't count
  24. // as missed traffic in the data plane.
  25. func newConnectionStateFromResult(r *handshake.Result) *ConnectionState {
  26. ci := &ConnectionState{
  27. myCert: r.MyCert,
  28. initiator: r.Initiator,
  29. peerCert: r.RemoteCert,
  30. eKey: noiseutil.NewCipherState(r.EKey, r.Cipher),
  31. dKey: noiseutil.NewCipherState(r.DKey, r.Cipher),
  32. window: NewBits(ReplayWindow),
  33. }
  34. ci.messageCounter.Add(r.MessageIndex)
  35. for i := uint64(1); i <= r.MessageIndex; i++ {
  36. ci.window.Update(nil, i)
  37. }
  38. return ci
  39. }
  40. func (cs *ConnectionState) MarshalJSON() ([]byte, error) {
  41. return json.Marshal(m{
  42. "certificate": cs.peerCert,
  43. "initiator": cs.initiator,
  44. "message_counter": cs.messageCounter.Load(),
  45. })
  46. }
  47. func (cs *ConnectionState) Curve() cert.Curve {
  48. return cs.myCert.Curve()
  49. }