Ported handshake - still need to test

This commit is contained in:
saxon 2018-07-24 21:30:50 +09:30
parent 3e0d1a01d2
commit 839738df13
1 changed files with 32 additions and 27 deletions

View File

@ -63,9 +63,12 @@ import (
"fmt" "fmt"
"log" "log"
"math" "math"
"math/rand"
"reflect" "reflect"
"strconv" "strconv"
"unsafe" "unsafe"
"github.com/chamaken/cgolmnl/inet"
) )
const ( const (
@ -145,9 +148,9 @@ const (
int64Size = 8 int64Size = 8
) )
//memmove copies n bytes from "from" to "to". func memmove(to, from unsafe.Pointer, n uintptr) {
//go:linkname memmove runtime.memmove copy(ptrToSlice(to, int(n)), ptrToSlice(from,int(n)))
func memmove(to, from unsafe.Pointer, n uintptr) }
// av_setDataFrame is a static const global in rtmp.c // av_setDataFrame is a static const global in rtmp.c
var setDataFrame = AVC("@setDataFrame") var setDataFrame = AVC("@setDataFrame")
@ -652,7 +655,7 @@ func rtmpConnect0(r *C.RTMP, service *C.sockaddr) int {
r.m_sb.sb_socket = C.socket(C.AF_INET, C.SOCK_STREAM, C.IPPROTO_TCP) r.m_sb.sb_socket = C.socket(C.AF_INET, C.SOCK_STREAM, C.IPPROTO_TCP)
if r.m_sb.sb_socket != -1 { if r.m_sb.sb_socket != -1 {
if C.connect(r.m_sb.sb_socket, service, C.uint(unsafe.Sizeof(*service))) < 0 { if C.connect(r.m_sb.sb_socket, service, C.socklen_t(unsafe.Sizeof(*service))) < 0 {
log.Println("rtmpConnect0, failed to connect socket.") log.Println("rtmpConnect0, failed to connect socket.")
} }
@ -675,13 +678,13 @@ func rtmpConnect0(r *C.RTMP, service *C.sockaddr) int {
tv := C.int(r.Link.timeout * 1000) tv := C.int(r.Link.timeout * 1000)
if C.setsockopt(r.m_sb.sb_socket, C.SOL_SOCKET, C.SO_RCVTIMEO, if C.setsockopt(r.m_sb.sb_socket, C.SOL_SOCKET, C.SO_RCVTIMEO,
unsafe.Pointer(&tv), C.uint(unsafe.Sizeof(tv))) != 0 { unsafe.Pointer(&tv), C.socklen_t(unsafe.Sizeof(tv))) != 0 {
log.Println("rtmpConnect0: Setting socket timeout failed") log.Println("rtmpConnect0: Setting socket timeout failed")
} }
} }
C.setsockopt(r.m_sb.sb_socket, C.IPPROTO_TCP, C.TCP_NODELAY, C.setsockopt(r.m_sb.sb_socket, C.IPPROTO_TCP, C.TCP_NODELAY,
unsafe.Pointer(&on), C.uint(unsafe.Sizeof(on))) unsafe.Pointer(&on), C.socklen_t(unsafe.Sizeof(on)))
return 1 return 1
} }
@ -709,15 +712,17 @@ func rtmpConnect1(r *C.RTMP, cp *C.RTMPPacket) int {
// TODO: complete this // TODO: complete this
func handShake(r *C.RTMP, FP9HandShake int32) int { func handShake(r *C.RTMP, FP9HandShake int32) int {
var i, bMatch int var bMatch int
//uptime := uint32(0)
//suptime := uint32(0)
//typ := byte(0)
var uptime, suptime uint32 var uptime, suptime uint32
var typ byte var typ byte
// TODO: port this const //clientbuf := make([]byte, RTMP_SIG_SIZE+1)
var clientbuf [RTMP_SIG_SIZE + 1]byte var clientbuf [RTMP_SIG_SIZE + 1]byte
clientsig := (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&clientbuf[0])) + clientsig := (*byte)(incBytePtr(unsafe.Pointer(&clientbuf[0]), 1))
uintptr(1))) //serversig := make([]byte, RTMP_SIG_SIZE)
var serversig [RTMP_SIG_SIZE]byte var serversig [RTMP_SIG_SIZE]byte
clientbuf[0] = 0x03 // not encrypted clientbuf[0] = 0x03 // not encrypted
@ -732,43 +737,44 @@ func handShake(r *C.RTMP, FP9HandShake int32) int {
*indxBytePtr(unsafe.Pointer(clientsig), i) = byte(rand.Intn(256)) *indxBytePtr(unsafe.Pointer(clientsig), i) = byte(rand.Intn(256))
} }
if writeN(r, clientbuf, RTMP_SIG_SIZE+1) == 0 { if writeN(r, unsafe.Pointer(&clientbuf[0]), RTMP_SIG_SIZE+1) == 0 {
return 0 return 0
} }
// TODO: port this // TODO: port this
if ReadN(r, &type, 1) != 1 { if C.ReadN(r, (*C.char)(unsafe.Pointer(&typ)), 1) != 1 {
return 0 return 0
} }
if debugMode { if debugMode {
log.Println("handShake: Type answer: %v", t) log.Println("handShake: Type answer: %v", typ)
} }
if t != clientbuf[0] { if typ != clientbuf[0] {
log.Println("handShake: type mismatch: client sent %v, server sent: %v", log.Println("handShake: type mismatch: client sent %v, server sent: %v",
clientbuf[0], t) clientbuf[0], typ)
} }
if ReadN(r, serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE { if C.ReadN(r, (*C.char)(unsafe.Pointer(&serversig[0])), RTMP_SIG_SIZE) != RTMP_SIG_SIZE {
return 0 return 0
} }
// decode server response // decode server response
memmove(unsafe.Pointer(&suptime), serversig, 4) memmove(unsafe.Pointer(&suptime), unsafe.Pointer(&serversig[0]), 4)
suptime = inet.Ntohl(suptime) suptime = inet.Ntohl(suptime)
// 2nd part of handshake // 2nd part of handshake
if writeN(r, serversig, RTMP_SIG_SIZE) == 0 { if writeN(r, unsafe.Pointer(&serversig[0]), RTMP_SIG_SIZE) == 0 {
return 0 return 0
} }
if ReadN(r, serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE { if C.ReadN(r, (*C.char)(unsafe.Pointer(&serversig[0])), RTMP_SIG_SIZE) != RTMP_SIG_SIZE {
return 0 return 0
} }
// TODO: find golang memcmp // TODO: find golang memcmp
bMatch = 0 bMatch = 0
if memcmp(serversig,clientsig,RTMP_SIG_SIZE) == 0 { if memcmp(unsafe.Pointer(&serversig[0]), unsafe.Pointer(clientsig),
RTMP_SIG_SIZE) == 0 {
bMatch = 1 bMatch = 1
} }
@ -900,8 +906,7 @@ func rtmpWrite(r *C.RTMP, data []byte) int {
num = s2 num = s2
} }
//memmove(enc,buf,uintptr(num)) memmove(enc,buf,uintptr(num))
copy(ptrToSlice(enc, num), ptrToSlice(buf, num))
pkt.m_nBytesRead += C.uint32_t(num) pkt.m_nBytesRead += C.uint32_t(num)
s2 -= num s2 -= num
buf = incBytePtr(buf, num) buf = incBytePtr(buf, num)
@ -1387,11 +1392,11 @@ func avQueue(vals **C.RTMP_METHOD, num *int, av *C.AVal, txn int) {
int(unsafe.Sizeof(rtmpMethodPtr))))).name.av_val = (*C.char)(tmp) int(unsafe.Sizeof(rtmpMethodPtr))))).name.av_val = (*C.char)(tmp)
} }
// TODO: write test for this func // TODO: write test for this func
func memcmp(a,b unsafe.Pointer, size int) int { func memcmp(a, b unsafe.Pointer, size int) int {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
aValue := *indxBytePtr(a,i) aValue := *indxBytePtr(a, i)
bValue := *indxBytePtr(b,i) bValue := *indxBytePtr(b, i)
if aValue != bValue { if aValue != bValue {
if aValue < bValue { if aValue < bValue {
return -1 return -1