-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
For the DJI M30, there is a bug where empty NALU packets with a size of zero are causing issues with HLS streaming. This bug leads to random unpublish events due to the SRS disconnecting the connection for the HLS module when it fails to handle empty NALU packets. To address this bug, we have patched the system to ignore any empty NALU packets with a size of zero. Additionally, we have created a tool in the srs-bench to replay pcapng files captured by tcpdump or Wireshark. We have also added utest using mprotect and asan to detect any memory corruption. It is important to note that this bug has been fixed in versions 4.0.271 6477f31 and 5.0.170 939f6b4. This patch specifically addresses the issue in SRS 6.0. Please be aware that there is another commit related to this bug that partially fixes the issue but still leaves a small problem for asan to detect memory corruption. This commit, 577cd29, only ignores empty NALU packets but still reads beyond the memory. --------- Co-authored-by: chundonglinlin <[email protected]>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,4 +7,5 @@ objs | |
|
||
.format.txt | ||
.DS_Store | ||
*.log | ||
*.log | ||
*.pcapng |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"context" | ||
"flag" | ||
"fmt" | ||
"net" | ||
"os" | ||
"time" | ||
|
||
"github.com/google/gopacket" | ||
"github.com/google/gopacket/layers" | ||
"github.com/google/gopacket/pcapgo" | ||
"github.com/ossrs/go-oryx-lib/errors" | ||
"github.com/ossrs/go-oryx-lib/logger" | ||
) | ||
|
||
func main() { | ||
ctx := logger.WithContext(context.Background()) | ||
if err := doMain(ctx); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
func trace(format string, args ...interface{}) { | ||
fmt.Println(fmt.Sprintf(format, args...)) | ||
} | ||
|
||
func doMain(ctx context.Context) error { | ||
var doRE, doTrace, help bool | ||
var pauseNumber, abortNumber uint64 | ||
var filename string | ||
var server string | ||
flag.BoolVar(&help, "h", false, "whether show this help") | ||
flag.BoolVar(&help, "help", false, "whether show this help") | ||
flag.BoolVar(&doRE, "re", true, "whether do real-time emulation") | ||
flag.BoolVar(&doTrace, "trace", true, "whether trace the packet") | ||
flag.Uint64Var(&pauseNumber, "pause", 0, "the packet number to pause") | ||
flag.Uint64Var(&abortNumber, "abort", 0, "the packet number to abort") | ||
flag.StringVar(&filename, "f", "", "the pcap filename, like ./t.pcapng") | ||
flag.StringVar(&server, "s", "", "the server address, like 127.0.0.1:1935") | ||
|
||
flag.Parse() | ||
|
||
if help { | ||
flag.Usage() | ||
os.Exit(0) | ||
} | ||
|
||
if filename == "" || server == "" { | ||
flag.Usage() | ||
os.Exit(1) | ||
} | ||
|
||
logger.Tf(ctx, "Forward pcap %v to %v, re=%v, trace=%v, pause=%v, abort=%v", | ||
filename, server, doRE, doTrace, pauseNumber, abortNumber) | ||
|
||
f, err := os.Open(filename) | ||
if err != nil { | ||
return errors.Wrapf(err, "open pcap %v", filename) | ||
} | ||
defer f.Close() | ||
|
||
r, err := pcapgo.NewNgReader(f, pcapgo.DefaultNgReaderOptions) | ||
if err != nil { | ||
return errors.Wrapf(err, "new reader") | ||
} | ||
|
||
// TODO: FIXME: Should start a goroutine to consume bytes from conn. | ||
conn, err := net.Dial("tcp", server) | ||
if err != nil { | ||
return errors.Wrapf(err, "dial %v", server) | ||
} | ||
defer conn.Close() | ||
|
||
var packetNumber uint64 | ||
var previousTime *time.Time | ||
source := gopacket.NewPacketSource(r, r.LinkType()) | ||
for packet := range source.Packets() { | ||
packetNumber++ | ||
|
||
if packet.Layer(layers.LayerTypeTCP) == nil { | ||
continue | ||
} | ||
|
||
ci := packet.Metadata().CaptureInfo | ||
tcp, _ := packet.Layer(layers.LayerTypeTCP).(*layers.TCP) | ||
payload := tcp.Payload | ||
if len(payload) == 0 { | ||
continue | ||
} | ||
if tcp.DstPort != 1935 { | ||
continue | ||
} | ||
|
||
if pauseNumber > 0 && packetNumber == pauseNumber { | ||
reader := bufio.NewReader(os.Stdin) | ||
trace("#%v Press Enter to continue...", packetNumber) | ||
_, _ = reader.ReadString('\n') | ||
} | ||
if abortNumber > 0 && packetNumber > abortNumber { | ||
break | ||
} | ||
|
||
if _, err := conn.Write(payload); err != nil { | ||
return errors.Wrapf(err, "write to %v", server) | ||
} | ||
|
||
if doRE { | ||
if previousTime != nil { | ||
if diff := ci.Timestamp.Sub(*previousTime); diff > 0 { | ||
time.Sleep(diff) | ||
} | ||
} | ||
previousTime = &ci.Timestamp | ||
} | ||
|
||
if doTrace { | ||
trace("#%v TCP %v=>%v %v Len:%v", | ||
packetNumber, uint16(tcp.SrcPort), uint16(tcp.DstPort), | ||
ci.Timestamp.Format("15:04:05.000"), | ||
len(payload)) | ||
} | ||
} | ||
|
||
return nil | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.