server.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package srtp
  2. import (
  3. "encoding/binary"
  4. "net"
  5. "strconv"
  6. "sync"
  7. )
  8. type Server struct {
  9. address string
  10. conn net.PacketConn
  11. sessions map[uint32]*Session
  12. mu sync.Mutex
  13. }
  14. func NewServer(address string) *Server {
  15. return &Server{
  16. address: address,
  17. sessions: map[uint32]*Session{},
  18. }
  19. }
  20. func (s *Server) Port() int {
  21. if s.conn != nil {
  22. return s.conn.LocalAddr().(*net.UDPAddr).Port
  23. }
  24. _, a, _ := net.SplitHostPort(s.address)
  25. i, _ := strconv.Atoi(a)
  26. return i
  27. }
  28. func (s *Server) AddSession(session *Session) {
  29. s.mu.Lock()
  30. defer s.mu.Unlock()
  31. if err := session.init(); err != nil {
  32. return
  33. }
  34. if len(s.sessions) == 0 {
  35. var err error
  36. if s.conn, err = net.ListenPacket("udp", s.address); err != nil {
  37. return
  38. }
  39. go s.handle()
  40. }
  41. session.conn = s.conn
  42. s.sessions[session.Remote.SSRC] = session
  43. }
  44. func (s *Server) DelSession(session *Session) {
  45. s.mu.Lock()
  46. delete(s.sessions, session.Remote.SSRC)
  47. // check s.conn for https://github.com/AlexxIT/go2rtc/issues/734
  48. if len(s.sessions) == 0 && s.conn != nil {
  49. _ = s.conn.Close()
  50. }
  51. s.mu.Unlock()
  52. }
  53. func (s *Server) handle() error {
  54. b := make([]byte, 2048)
  55. for {
  56. n, _, err := s.conn.ReadFrom(b)
  57. if err != nil {
  58. return err
  59. }
  60. // Multiplexing RTP Data and Control Packets on a Single Port
  61. // https://datatracker.ietf.org/doc/html/rfc5761
  62. switch packetType := b[1]; packetType {
  63. case 99, 110, 0x80 | 99, 0x80 | 110:
  64. // this is default position for SSRC in RTP packet
  65. ssrc := binary.BigEndian.Uint32(b[8:])
  66. if session, ok := s.sessions[ssrc]; ok {
  67. session.ReadRTP(b[:n])
  68. }
  69. case 200, 201, 202, 203, 204, 205, 206, 207:
  70. // this is default position for SSRC in RTCP packet
  71. ssrc := binary.BigEndian.Uint32(b[4:])
  72. if session, ok := s.sessions[ssrc]; ok {
  73. session.ReadRTCP(b[:n])
  74. }
  75. }
  76. }
  77. }