summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/srtp/v2/session.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pion/srtp/v2/session.go')
-rw-r--r--vendor/github.com/pion/srtp/v2/session.go150
1 files changed, 150 insertions, 0 deletions
diff --git a/vendor/github.com/pion/srtp/v2/session.go b/vendor/github.com/pion/srtp/v2/session.go
new file mode 100644
index 0000000..95520f7
--- /dev/null
+++ b/vendor/github.com/pion/srtp/v2/session.go
@@ -0,0 +1,150 @@
+package srtp
+
+import (
+ "io"
+ "net"
+ "sync"
+
+ "github.com/pion/logging"
+ "github.com/pion/transport/packetio"
+)
+
+type streamSession interface {
+ Close() error
+ write([]byte) (int, error)
+ decrypt([]byte) error
+}
+
+type session struct {
+ localContextMutex sync.Mutex
+ localContext, remoteContext *Context
+ localOptions, remoteOptions []ContextOption
+
+ newStream chan readStream
+
+ started chan interface{}
+ closed chan interface{}
+
+ readStreamsClosed bool
+ readStreams map[uint32]readStream
+ readStreamsLock sync.Mutex
+
+ log logging.LeveledLogger
+ bufferFactory func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser
+
+ nextConn net.Conn
+}
+
+// Config is used to configure a session.
+// You can provide either a KeyingMaterialExporter to export keys
+// or directly pass the keys themselves.
+// After a Config is passed to a session it must not be modified.
+type Config struct {
+ Keys SessionKeys
+ Profile ProtectionProfile
+ BufferFactory func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser
+ LoggerFactory logging.LoggerFactory
+
+ // List of local/remote context options.
+ // ReplayProtection is enabled on remote context by default.
+ // Default replay protection window size is 64.
+ LocalOptions, RemoteOptions []ContextOption
+}
+
+// SessionKeys bundles the keys required to setup an SRTP session
+type SessionKeys struct {
+ LocalMasterKey []byte
+ LocalMasterSalt []byte
+ RemoteMasterKey []byte
+ RemoteMasterSalt []byte
+}
+
+func (s *session) getOrCreateReadStream(ssrc uint32, child streamSession, proto func() readStream) (readStream, bool) {
+ s.readStreamsLock.Lock()
+ defer s.readStreamsLock.Unlock()
+
+ if s.readStreamsClosed {
+ return nil, false
+ }
+
+ r, ok := s.readStreams[ssrc]
+ if ok {
+ return r, false
+ }
+
+ // Create the readStream.
+ r = proto()
+
+ if err := r.init(child, ssrc); err != nil {
+ return nil, false
+ }
+
+ s.readStreams[ssrc] = r
+ return r, true
+}
+
+func (s *session) removeReadStream(ssrc uint32) {
+ s.readStreamsLock.Lock()
+ defer s.readStreamsLock.Unlock()
+
+ if s.readStreamsClosed {
+ return
+ }
+
+ delete(s.readStreams, ssrc)
+}
+
+func (s *session) close() error {
+ if s.nextConn == nil {
+ return nil
+ } else if err := s.nextConn.Close(); err != nil {
+ return err
+ }
+
+ <-s.closed
+ return nil
+}
+
+func (s *session) start(localMasterKey, localMasterSalt, remoteMasterKey, remoteMasterSalt []byte, profile ProtectionProfile, child streamSession) error {
+ var err error
+ s.localContext, err = CreateContext(localMasterKey, localMasterSalt, profile, s.localOptions...)
+ if err != nil {
+ return err
+ }
+
+ s.remoteContext, err = CreateContext(remoteMasterKey, remoteMasterSalt, profile, s.remoteOptions...)
+ if err != nil {
+ return err
+ }
+
+ go func() {
+ defer func() {
+ close(s.newStream)
+
+ s.readStreamsLock.Lock()
+ s.readStreamsClosed = true
+ s.readStreamsLock.Unlock()
+ close(s.closed)
+ }()
+
+ b := make([]byte, 8192)
+ for {
+ var i int
+ i, err = s.nextConn.Read(b)
+ if err != nil {
+ if err != io.EOF {
+ s.log.Error(err.Error())
+ }
+ return
+ }
+
+ if err = child.decrypt(b[:i]); err != nil {
+ s.log.Info(err.Error())
+ }
+ }
+ }()
+
+ close(s.started)
+
+ return nil
+}