connection_state.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package nebula
  2. import (
  3. "crypto/rand"
  4. "encoding/json"
  5. "sync"
  6. "sync/atomic"
  7. "github.com/flynn/noise"
  8. "github.com/sirupsen/logrus"
  9. "github.com/slackhq/nebula/cert"
  10. "github.com/slackhq/nebula/noiseutil"
  11. )
  12. const ReplayWindow = 1024
  13. type ConnectionState struct {
  14. eKey *NebulaCipherState
  15. dKey *NebulaCipherState
  16. H *noise.HandshakeState
  17. certState *CertState
  18. peerCert *cert.NebulaCertificate
  19. initiator bool
  20. messageCounter atomic.Uint64
  21. window *Bits
  22. queueLock sync.Mutex
  23. writeLock sync.Mutex
  24. ready bool
  25. }
  26. func (f *Interface) newConnectionState(l *logrus.Logger, initiator bool, pattern noise.HandshakePattern, psk []byte, pskStage int) *ConnectionState {
  27. cs := noise.NewCipherSuite(noise.DH25519, noiseutil.CipherAESGCM, noise.HashSHA256)
  28. if f.cipher == "chachapoly" {
  29. cs = noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256)
  30. }
  31. curCertState := f.certState.Load()
  32. static := noise.DHKey{Private: curCertState.privateKey, Public: curCertState.publicKey}
  33. b := NewBits(ReplayWindow)
  34. // Clear out bit 0, we never transmit it and we don't want it showing as packet loss
  35. b.Update(l, 0)
  36. hs, err := noise.NewHandshakeState(noise.Config{
  37. CipherSuite: cs,
  38. Random: rand.Reader,
  39. Pattern: pattern,
  40. Initiator: initiator,
  41. StaticKeypair: static,
  42. PresharedKey: psk,
  43. PresharedKeyPlacement: pskStage,
  44. })
  45. if err != nil {
  46. return nil
  47. }
  48. // The queue and ready params prevent a counter race that would happen when
  49. // sending stored packets and simultaneously accepting new traffic.
  50. ci := &ConnectionState{
  51. H: hs,
  52. initiator: initiator,
  53. window: b,
  54. ready: false,
  55. certState: curCertState,
  56. }
  57. return ci
  58. }
  59. func (cs *ConnectionState) MarshalJSON() ([]byte, error) {
  60. return json.Marshal(m{
  61. "certificate": cs.peerCert,
  62. "initiator": cs.initiator,
  63. "message_counter": cs.messageCounter.Load(),
  64. "ready": cs.ready,
  65. })
  66. }