connection_state.go 2.0 KB

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