From b2c3ca552bdc0484d50491974968bc0d53b5a67c Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Wed, 9 Aug 2023 16:00:21 +0500 Subject: [PATCH] Basic RTMP server+handshake --- go.mod | 3 +++ ingest.go | 12 ++++++++++++ main.go | 15 +++++++++++++++ rtmp/connect.go | 9 +++++++++ rtmp/handshake.go | 33 +++++++++++++++++++++++++++++++++ rtmp/server.go | 41 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+) create mode 100644 go.mod create mode 100644 ingest.go create mode 100644 main.go create mode 100644 rtmp/connect.go create mode 100644 rtmp/handshake.go create mode 100644 rtmp/server.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..45875ee --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module stream_server + +go 1.20 diff --git a/ingest.go b/ingest.go new file mode 100644 index 0000000..4fb0786 --- /dev/null +++ b/ingest.go @@ -0,0 +1,12 @@ +package main + +import "stream_server/rtmp" + +func NewIngestServer(srvr_type uint8, port string) (error) { + var err error + switch srvr_type { + case 0: + err = rtmp.NewServer(&port) + } + return err +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..1f6c411 --- /dev/null +++ b/main.go @@ -0,0 +1,15 @@ +package main + +const ( + SRVTYPE_RTMP uint8 = iota +) + +func main() { + err := NewIngestServer(SRVTYPE_RTMP, "7878") + if err != nil { + panic(err) + } + + for { + } +} diff --git a/rtmp/connect.go b/rtmp/connect.go new file mode 100644 index 0000000..6891156 --- /dev/null +++ b/rtmp/connect.go @@ -0,0 +1,9 @@ +package rtmp + +import ( + "net" +) + +func NegotiateConnect(conn net.Conn) { + +} diff --git a/rtmp/handshake.go b/rtmp/handshake.go new file mode 100644 index 0000000..fcc60d5 --- /dev/null +++ b/rtmp/handshake.go @@ -0,0 +1,33 @@ +package rtmp + +import ( + "net" + "time" + "encoding/binary" +) + +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())) + + conn.SetDeadline(time.Now().Add(15 * time.Second)) + + if _, err := conn.Read(C0C1C2); err != nil || C0C1C2[0] != 3 { + return + } + copy(C0C1C2[1:1536], S0S1S2[1+1536:]) + binary.BigEndian.PutUint32(S0S1S2[1+1536+4:1+1536+8], uint32(time.Now().UnixMilli())) + + if _, err := conn.Write(S0S1S2); err != nil { + return + } + if _, err := conn.Read(C0C1C2[1+1536:]); err != nil { + return + } + hs_success = true + conn.SetDeadline(time.Time{}) + return +} diff --git a/rtmp/server.go b/rtmp/server.go new file mode 100644 index 0000000..30a77c3 --- /dev/null +++ b/rtmp/server.go @@ -0,0 +1,41 @@ +package rtmp + +import ( + "net" +) + +func NewServer(port *string) (error) { + l, err := net.Listen("tcp", ":" + *port) + if err != nil { + return err + } + go start(l) + return nil +} + +func start(l net.Listener) { + stream_live := false + for { + conn, err := l.Accept() + if err != nil { + continue + } else if stream_live { + conn.Close() + continue + } + stream_live = true + go handle_conn(conn, &stream_live) + } +} + +func handle_conn(conn net.Conn, stream_live *bool) { + defer conn.Close() + if !DoHandshake(conn) { + return + } + if !NegoiateConnect(conn) { + return + } + + *stream_live = false +}