2023-08-09 16:00:21 +05:00
|
|
|
package rtmp
|
|
|
|
|
|
|
|
import (
|
2024-03-11 14:00:21 +05:00
|
|
|
"io"
|
2023-08-09 16:00:21 +05:00
|
|
|
"net"
|
|
|
|
"time"
|
|
|
|
"encoding/binary"
|
|
|
|
)
|
|
|
|
|
2023-08-21 20:25:54 +05:00
|
|
|
// see adobe specs for RTMP
|
2023-08-09 16:00:21 +05:00
|
|
|
func DoHandshake(conn net.Conn) (hs_success bool) {
|
|
|
|
C0C1C2 := make([]byte, 1536*2 + 1)
|
|
|
|
S0S1S2 := make([]byte, 1536*2 + 1)
|
|
|
|
|
|
|
|
S0S1S2[0] = 3
|
|
|
|
binary.BigEndian.PutUint32(S0S1S2[1:1+4], uint32(time.Now().UnixMilli()))
|
|
|
|
|
2023-08-21 20:25:54 +05:00
|
|
|
// force handshake to finish in under 15 seconds (aribtrary) or throw an error
|
2023-08-09 16:00:21 +05:00
|
|
|
conn.SetDeadline(time.Now().Add(15 * time.Second))
|
|
|
|
|
2024-03-11 14:00:21 +05:00
|
|
|
if _, err := io.ReadFull(conn, C0C1C2); err != nil || C0C1C2[0] != 3 {
|
2023-08-09 16:00:21 +05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
copy(C0C1C2[1:1536], S0S1S2[1+1536:])
|
|
|
|
binary.BigEndian.PutUint32(S0S1S2[1+1536+4:1+1536+8], uint32(time.Now().UnixMilli()))
|
|
|
|
|
2023-08-21 20:25:54 +05:00
|
|
|
if _, err := conn.Write(S0S1S2); err != nil { // specs say only send S0S1 and wait for C2 before sending S2, obs doesn't care apparently
|
2023-08-09 16:00:21 +05:00
|
|
|
return
|
|
|
|
}
|
2024-03-11 14:00:21 +05:00
|
|
|
if _, err := io.ReadFull(conn, C0C1C2[1+1536:]); err != nil {
|
2023-08-09 16:00:21 +05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
hs_success = true
|
2023-08-21 20:25:54 +05:00
|
|
|
conn.SetDeadline(time.Time{}) // remove deadline for next function
|
2023-08-09 16:00:21 +05:00
|
|
|
return
|
|
|
|
}
|