@@ -2,10 +2,13 @@ package rtmp
2
2
3
3
import (
4
4
"bufio"
5
+ "crypto/rand"
5
6
"encoding/binary"
7
+ "errors"
6
8
"fmt"
7
9
"io"
8
10
"net"
11
+ "time"
9
12
10
13
"github.com/AlexxIT/go2rtc/pkg/core"
11
14
"github.com/AlexxIT/go2rtc/pkg/flv/amf"
@@ -34,23 +37,54 @@ func NewServer(conn net.Conn) (*Conn, error) {
34
37
}
35
38
36
39
func (c * Conn ) serverHandshake () error {
37
- b := make ([]byte , 1 + 1536 )
38
- // read C0+C1
40
+ // based on https://rtmp.veriskope.com/docs/spec/
41
+ _ = c .conn .SetDeadline (time .Now ().Add (core .ConnDeadline ))
42
+
43
+ // read C0
44
+ b := make ([]byte , 1 )
39
45
if _ , err := io .ReadFull (c .rd , b ); err != nil {
40
46
return err
41
47
}
42
- // write S0+S1, skip random
48
+
49
+ if b [0 ] != 3 {
50
+ return errors .New ("rtmp: wrong handshake" )
51
+ }
52
+
53
+ // write S0
54
+ if _ , err := c .conn .Write ([]byte {3 }); err != nil {
55
+ return err
56
+ }
57
+
58
+ b = make ([]byte , 1536 )
59
+
60
+ // write S1
61
+ tsS1 := nowMS ()
62
+ binary .BigEndian .PutUint32 (b , tsS1 )
63
+ binary .BigEndian .PutUint32 (b [4 :], 0 )
64
+ _ , _ = rand .Read (b [8 :])
43
65
if _ , err := c .conn .Write (b ); err != nil {
44
66
return err
45
67
}
46
- // read S1, skip check
47
- if _ , err := io .ReadFull (c .rd , make ([]byte , 1536 )); err != nil {
68
+
69
+ // read C1
70
+ if _ , err := io .ReadFull (c .rd , b ); err != nil {
48
71
return err
49
72
}
50
- // write C1
51
- if _ , err := c .conn .Write (b [1 :]); err != nil {
73
+
74
+ // write S2
75
+ tsS2 := nowMS ()
76
+ binary .BigEndian .PutUint32 (b , tsS1 )
77
+ binary .BigEndian .PutUint32 (b [4 :], tsS2 )
78
+ if _ , err := c .conn .Write (b ); err != nil {
52
79
return err
53
80
}
81
+
82
+ // read C2
83
+ if _ , err := io .ReadFull (c .rd , b ); err != nil {
84
+ return err
85
+ }
86
+
87
+ _ = c .conn .SetDeadline (time.Time {})
54
88
return nil
55
89
}
56
90
@@ -161,3 +195,7 @@ func (c *Conn) WriteStart() error {
161
195
payload := amf .EncodeItems ("onStatus" , 0 , nil , map [string ]any {"code" : code })
162
196
return c .writeMessage (3 , TypeCommand , 0 , payload )
163
197
}
198
+
199
+ func nowMS () uint32 {
200
+ return uint32 (time .Now ().UnixNano () / int64 (time .Millisecond ))
201
+ }
0 commit comments