connection_state.go 1.4 KB

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