mirror of
https://github.com/datarhei/core.git
synced 2025-10-07 00:43:39 +08:00
Create publisher for remote srt stream
This commit is contained in:
4
vendor/github.com/datarhei/gosrt/Makefile
generated
vendored
4
vendor/github.com/datarhei/gosrt/Makefile
generated
vendored
@@ -5,7 +5,7 @@ all: build
|
||||
|
||||
## test: Run all tests
|
||||
test:
|
||||
go test -race -coverprofile=/dev/null -timeout 15s -v ./...
|
||||
go test -race -coverprofile=/dev/null -timeout 60s -v ./...
|
||||
|
||||
## vet: Analyze code for potential errors
|
||||
vet:
|
||||
@@ -43,7 +43,7 @@ server:
|
||||
|
||||
## coverage: Generate code coverage analysis
|
||||
coverage:
|
||||
go test -race -coverprofile=cover.out -timeout 15s -v ./...
|
||||
go test -race -coverprofile=cover.out -timeout 60s -v ./...
|
||||
go tool cover -html=cover.out -o cover.html
|
||||
|
||||
## commit: Prepare code for commit (vet, fmt, test)
|
||||
|
8
vendor/github.com/datarhei/gosrt/config.go
generated
vendored
8
vendor/github.com/datarhei/gosrt/config.go
generated
vendored
@@ -218,17 +218,17 @@ func DefaultConfig() Config {
|
||||
|
||||
// UnmarshalURL takes a SRT URL and parses out the configuration. A SRT URL is
|
||||
// srt://[host]:[port]?[key1]=[value1]&[key2]=[value2]...
|
||||
func (c *Config) UnmarshalURL(addr string) error {
|
||||
func (c *Config) UnmarshalURL(addr string) (string, error) {
|
||||
u, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
|
||||
if u.Scheme != "srt" {
|
||||
return fmt.Errorf("the URL doesn't seem to be an srt:// URL")
|
||||
return "", fmt.Errorf("the URL doesn't seem to be an srt:// URL")
|
||||
}
|
||||
|
||||
return c.UnmarshalQuery(u.RawQuery)
|
||||
return u.Host, c.UnmarshalQuery(u.RawQuery)
|
||||
}
|
||||
|
||||
// UnmarshalQuery parses a query string and interprets it as a configuration
|
||||
|
20
vendor/github.com/datarhei/gosrt/connection.go
generated
vendored
20
vendor/github.com/datarhei/gosrt/connection.go
generated
vendored
@@ -93,6 +93,7 @@ type srtConn struct {
|
||||
|
||||
config Config
|
||||
|
||||
cryptoLock sync.Mutex
|
||||
crypto crypto.Crypto
|
||||
keyBaseEncryption packet.PacketEncryption
|
||||
kmPreAnnounceCountdown uint64
|
||||
@@ -453,6 +454,7 @@ func (c *srtConn) pop(p packet.Packet) {
|
||||
p.Header().DestinationSocketId = c.peerSocketId
|
||||
|
||||
if !p.Header().IsControlPacket {
|
||||
c.cryptoLock.Lock()
|
||||
if c.crypto != nil {
|
||||
p.Header().KeyBaseEncryptionFlag = c.keyBaseEncryption
|
||||
c.crypto.EncryptOrDecryptPayload(p.Data(), p.Header().KeyBaseEncryptionFlag, p.Header().PacketSequenceNumber.Val())
|
||||
@@ -483,6 +485,7 @@ func (c *srtConn) pop(p packet.Packet) {
|
||||
c.crypto.GenerateSEK(c.keyBaseEncryption.Opposite())
|
||||
}
|
||||
}
|
||||
c.cryptoLock.Unlock()
|
||||
|
||||
c.log("data:send:dump", func() string { return p.Dump() })
|
||||
}
|
||||
@@ -614,6 +617,7 @@ func (c *srtConn) handlePacket(p packet.Packet) {
|
||||
|
||||
c.log("data:recv:dump", func() string { return p.Dump() })
|
||||
|
||||
c.cryptoLock.Lock()
|
||||
if c.crypto != nil {
|
||||
if header.KeyBaseEncryptionFlag != 0 {
|
||||
if err := c.crypto.EncryptOrDecryptPayload(p.Data(), header.KeyBaseEncryptionFlag, header.PacketSequenceNumber.Val()); err != nil {
|
||||
@@ -625,6 +629,7 @@ func (c *srtConn) handlePacket(p packet.Packet) {
|
||||
c.statistics.byteRecvUndecrypt += p.Len()
|
||||
}
|
||||
}
|
||||
c.cryptoLock.Unlock()
|
||||
|
||||
// Put the packet into receive congestion control
|
||||
c.recv.Push(p)
|
||||
@@ -759,8 +764,11 @@ func (c *srtConn) handleKMRequest(p packet.Packet) {
|
||||
|
||||
c.statistics.pktRecvKM++
|
||||
|
||||
c.cryptoLock.Lock()
|
||||
|
||||
if c.crypto == nil {
|
||||
c.log("control:recv:KM:error", func() string { return "connection is not encrypted" })
|
||||
c.cryptoLock.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -769,6 +777,7 @@ func (c *srtConn) handleKMRequest(p packet.Packet) {
|
||||
if err := p.UnmarshalCIF(cif); err != nil {
|
||||
c.statistics.pktRecvInvalid++
|
||||
c.log("control:recv:KM:error", func() string { return fmt.Sprintf("invalid KM: %s", err) })
|
||||
c.cryptoLock.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -779,15 +788,23 @@ func (c *srtConn) handleKMRequest(p packet.Packet) {
|
||||
c.log("control:recv:KM:error", func() string {
|
||||
return "invalid KM. wants to reset the key that is already in use"
|
||||
})
|
||||
c.cryptoLock.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.crypto.UnmarshalKM(cif, c.config.Passphrase); err != nil {
|
||||
c.statistics.pktRecvInvalid++
|
||||
c.log("control:recv:KM:error", func() string { return fmt.Sprintf("invalid KM: %s", err) })
|
||||
c.cryptoLock.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Switch the keys
|
||||
c.keyBaseEncryption = c.keyBaseEncryption.Opposite()
|
||||
|
||||
c.cryptoLock.Unlock()
|
||||
|
||||
// Send KM Response
|
||||
p.Header().SubType = packet.EXTTYPE_KMRSP
|
||||
|
||||
c.statistics.pktSentKM++
|
||||
@@ -801,6 +818,9 @@ func (c *srtConn) handleKMResponse(p packet.Packet) {
|
||||
|
||||
c.statistics.pktRecvKM++
|
||||
|
||||
c.cryptoLock.Lock()
|
||||
defer c.cryptoLock.Unlock()
|
||||
|
||||
if c.crypto == nil {
|
||||
c.log("control:recv:KM:error", func() string { return "connection is not encrypted" })
|
||||
return
|
||||
|
25
vendor/github.com/datarhei/gosrt/dial.go
generated
vendored
25
vendor/github.com/datarhei/gosrt/dial.go
generated
vendored
@@ -66,7 +66,8 @@ type connResponse struct {
|
||||
// The address is of the form "host:port".
|
||||
//
|
||||
// Example:
|
||||
// Dial("srt", "127.0.0.1:3000", DefaultConfig())
|
||||
//
|
||||
// Dial("srt", "127.0.0.1:3000", DefaultConfig())
|
||||
//
|
||||
// In case of an error the returned Conn is nil and the error is non-nil.
|
||||
func Dial(network, address string, config Config) (Conn, error) {
|
||||
@@ -663,6 +664,17 @@ func (dl *dialer) Read(p []byte) (n int, err error) {
|
||||
return dl.conn.Read(p)
|
||||
}
|
||||
|
||||
func (dl *dialer) readPacket() (packet.Packet, error) {
|
||||
if err := dl.checkConnection(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dl.connLock.RLock()
|
||||
defer dl.connLock.RUnlock()
|
||||
|
||||
return dl.conn.readPacket()
|
||||
}
|
||||
|
||||
func (dl *dialer) Write(p []byte) (n int, err error) {
|
||||
if err := dl.checkConnection(); err != nil {
|
||||
return 0, err
|
||||
@@ -674,6 +686,17 @@ func (dl *dialer) Write(p []byte) (n int, err error) {
|
||||
return dl.conn.Write(p)
|
||||
}
|
||||
|
||||
func (dl *dialer) writePacket(p packet.Packet) error {
|
||||
if err := dl.checkConnection(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dl.connLock.RLock()
|
||||
defer dl.connLock.RUnlock()
|
||||
|
||||
return dl.conn.writePacket(p)
|
||||
}
|
||||
|
||||
func (dl *dialer) SetDeadline(t time.Time) error { return dl.conn.SetDeadline(t) }
|
||||
func (dl *dialer) SetReadDeadline(t time.Time) error { return dl.conn.SetReadDeadline(t) }
|
||||
func (dl *dialer) SetWriteDeadline(t time.Time) error { return dl.conn.SetWriteDeadline(t) }
|
||||
|
19
vendor/github.com/datarhei/gosrt/pubsub.go
generated
vendored
19
vendor/github.com/datarhei/gosrt/pubsub.go
generated
vendored
@@ -12,7 +12,7 @@ import (
|
||||
// PubSub is a publish/subscriber service for SRT connections.
|
||||
type PubSub interface {
|
||||
// Publish accepts a SRT connection where it reads from. It blocks
|
||||
// until the connection closes. The returned error indicated why it
|
||||
// until the connection closes. The returned error indicates why it
|
||||
// stopped. There can be only one publisher.
|
||||
Publish(c Conn) error
|
||||
|
||||
@@ -23,6 +23,11 @@ type PubSub interface {
|
||||
Subscribe(c Conn) error
|
||||
}
|
||||
|
||||
type packetReadWriter interface {
|
||||
readPacket() (packet.Packet, error)
|
||||
writePacket(p packet.Packet) error
|
||||
}
|
||||
|
||||
// pubSub is an implementation of the PubSub interface
|
||||
type pubSub struct {
|
||||
incoming chan packet.Packet
|
||||
@@ -102,28 +107,30 @@ func (pb *pubSub) Publish(c Conn) error {
|
||||
|
||||
var p packet.Packet
|
||||
var err error
|
||||
conn, ok := c.(*srtConn)
|
||||
conn, ok := c.(packetReadWriter)
|
||||
if !ok {
|
||||
err := fmt.Errorf("the provided connection is not a SRT connection")
|
||||
pb.logger.Print("pubsub:error", 0, 1, func() string { return err.Error() })
|
||||
return err
|
||||
}
|
||||
|
||||
pb.logger.Print("pubsub:publish", conn.SocketId(), 1, func() string { return "new publisher" })
|
||||
socketId := c.SocketId()
|
||||
|
||||
pb.logger.Print("pubsub:publish", socketId, 1, func() string { return "new publisher" })
|
||||
|
||||
pb.publish = true
|
||||
|
||||
for {
|
||||
p, err = conn.readPacket()
|
||||
if err != nil {
|
||||
pb.logger.Print("pubsub:error", conn.SocketId(), 1, func() string { return err.Error() })
|
||||
pb.logger.Print("pubsub:error", socketId, 1, func() string { return err.Error() })
|
||||
break
|
||||
}
|
||||
|
||||
select {
|
||||
case pb.incoming <- p:
|
||||
default:
|
||||
pb.logger.Print("pubsub:error", conn.SocketId(), 1, func() string { return "incoming queue is full" })
|
||||
pb.logger.Print("pubsub:error", socketId, 1, func() string { return "incoming queue is full" })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +142,7 @@ func (pb *pubSub) Publish(c Conn) error {
|
||||
func (pb *pubSub) Subscribe(c Conn) error {
|
||||
l := make(chan packet.Packet, 1024)
|
||||
socketId := c.SocketId()
|
||||
conn, ok := c.(*srtConn)
|
||||
conn, ok := c.(packetReadWriter)
|
||||
if !ok {
|
||||
err := fmt.Errorf("the provided connection is not a SRT connection")
|
||||
pb.logger.Print("pubsub:error", 0, 1, func() string { return err.Error() })
|
||||
|
Reference in New Issue
Block a user