- PoW (Hashcash) authentication - X.509 CA for phone number certificates (+0 XXX YYY ZZZ) - QUIC transport (hysteria quic-go fork) with ACME TLS - Custom append-only DB engine (from NikoGram) - Call signaling (dial/ring/accept/reject/end) - E2EE media relay (X25519 + ChaCha20-Poly1305) - Brutal congestion control (from hysteria) - Media datagram relay (Opus/VP9/H264/H265) - Graceful shutdown
82 lines
1.8 KiB
Go
82 lines
1.8 KiB
Go
package protocol
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"io"
|
|
|
|
"github.com/niko/qcc/pkg/types"
|
|
)
|
|
|
|
const MediaHeaderSize = 8 + 4 + 1 + 1 + 4
|
|
|
|
type MediaPacket struct {
|
|
CallID uint64
|
|
SeqNum uint32
|
|
Codec types.CodecType
|
|
Flags types.MediaFlags
|
|
Timestamp uint32
|
|
Payload []byte
|
|
}
|
|
|
|
func MarshalMediaPacket(pkt *MediaPacket) []byte {
|
|
size := MediaHeaderSize + len(pkt.Payload)
|
|
buf := make([]byte, size)
|
|
off := 0
|
|
binary.BigEndian.PutUint64(buf[off:], pkt.CallID)
|
|
off += 8
|
|
binary.LittleEndian.PutUint32(buf[off:], pkt.SeqNum)
|
|
off += 4
|
|
buf[off] = byte(pkt.Codec)
|
|
off++
|
|
buf[off] = byte(pkt.Flags)
|
|
off++
|
|
binary.BigEndian.PutUint32(buf[off:], pkt.Timestamp)
|
|
off += 4
|
|
copy(buf[off:], pkt.Payload)
|
|
return buf
|
|
}
|
|
|
|
func UnmarshalMediaPacket(data []byte) (*MediaPacket, bool) {
|
|
if len(data) < MediaHeaderSize {
|
|
return nil, false
|
|
}
|
|
pkt := &MediaPacket{}
|
|
off := 0
|
|
pkt.CallID = binary.BigEndian.Uint64(data[off:])
|
|
off += 8
|
|
pkt.SeqNum = binary.LittleEndian.Uint32(data[off:])
|
|
off += 4
|
|
pkt.Codec = types.CodecType(data[off])
|
|
off++
|
|
pkt.Flags = types.MediaFlags(data[off])
|
|
off++
|
|
pkt.Timestamp = binary.BigEndian.Uint32(data[off:])
|
|
off += 4
|
|
pkt.Payload = make([]byte, len(data)-off)
|
|
copy(pkt.Payload, data[off:])
|
|
return pkt, true
|
|
}
|
|
|
|
func ReadMediaPacket(r io.Reader) (*MediaPacket, error) {
|
|
header := make([]byte, MediaHeaderSize)
|
|
if _, err := io.ReadFull(r, header); err != nil {
|
|
return nil, err
|
|
}
|
|
pkt := &MediaPacket{}
|
|
off := 0
|
|
pkt.CallID = binary.BigEndian.Uint64(header[off:])
|
|
off += 8
|
|
pkt.SeqNum = binary.LittleEndian.Uint32(header[off:])
|
|
off += 4
|
|
pkt.Codec = types.CodecType(header[off])
|
|
off++
|
|
pkt.Flags = types.MediaFlags(header[off])
|
|
off++
|
|
pkt.Timestamp = binary.BigEndian.Uint32(header[off:])
|
|
payload, err := io.ReadAll(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
pkt.Payload = payload
|
|
return pkt, nil
|
|
}
|