Repository: Haivision/srt (C++)

Issue:
[BUG] Phantom zero packets received over a group connection when the transmission stopped
**Describe the bug**
SYMPTOM: The receiver party displays reception, and so shows the output, of 1316-byte packets more-less once per a second, while there are no data being transmitted

**To Reproduce**

Sender machine: `./srt-test-live udp://:5432 -g srt://*?type=backup one:5000 two:5000 -v`
(make sure there's no signal on the UDP input)

Receiver machine: `./srt-test-live srt://:5000?groupconnect=1 output.ts -v`

Result: The receiver machine shows
```
[. << ...  << 1316  ->  .] sent
```

Despite that it doesn't receive anything. Packets extracted are also stored in `output.ts` and contain only zeros.

**Expected behavior**
The receiver machine should see nothing received and kinda hangup.

**Additional context**
It's unknown whether the problem is in the SRT library or just the application, this needs to be further investigated.



Discussion:

Patch:
diff --git a/apps/apputil.hpp b/apps/apputil.hpp
index 773b96b36..6031668ba 100644
--- a/apps/apputil.hpp
+++ b/apps/apputil.hpp
@@ -68,8 +68,10 @@ inline void SysCleanupNetwork() {}
 
 #ifdef _WIN32
 inline int SysError() { return ::GetLastError(); }
+const int SysAGAIN = WSAEWOULDBLOCK;
 #else
 inline int SysError() { return errno; }
+const int SysAGAIN = EAGAIN;
 #endif
 
 sockaddr_any CreateAddr(const std::string& name, unsigned short port = 0, int pref_family = AF_UNSPEC);


Test patch:
diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp
index 625b91601..1cb49cb64 100755
--- a/testing/testmedia.cpp
+++ b/testing/testmedia.cpp
@@ -2296,12 +2296,19 @@ MediaPacket SrtSource::Read(size_t chunk)
         ::transmit_throw_on_interrupt = true;
         stat = srt_recvmsg2(m_sock, data.data(), chunk, &mctrl);
         ::transmit_throw_on_interrupt = false;
-        if (stat == SRT_ERROR)
+        if (stat != SRT_ERROR)
+        {
+            ready = true;
+        }
+        else
         {
+            int syserr = 0;
+            int err = srt_getlasterror(&syserr);
+
             if (!m_blocking_mode)
             {
                 // EAGAIN for SRT READING
-                if (srt_getlasterror(NULL) == SRT_EASYNCRCV)
+                if (err == SRT_EASYNCRCV)
                 {
 Epoll_again:
                     Verb() << "AGAIN: - waiting for data by epoll(" << srt_epoll << ")...";
@@ -2347,8 +2354,11 @@ MediaPacket SrtSource::Read(size_t chunk)
             {
                 // In blocking mode it uses a minimum of 1s timeout,
                 // and continues only if interrupt not requested.
-                if (srt_getlasterror(NULL) == SRT_EASYNCRCV)
+                if (!::transmit_int_state && (err == SRT_EASYNCRCV || err == SRT_ETIMEOUT))
+                {
+                    ready = false;
                     continue;
+                }
             }
             Error("srt_recvmsg2");
         }
@@ -2890,6 +2900,11 @@ class UdpSource: public virtual Source, public virtual UdpCommon
         if (stat == -1)
             Error(SysError(), "Binding address for UDP");
         eof = false;
+        struct timeval tv;
+        tv.tv_sec = 1;
+        tv.tv_usec = 0;
+        if (::setsockopt(m_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
+            Error(SysError(), "Setting timeout for UDP");
     }
 
     MediaPacket Read(size_t chunk) override
@@ -2897,13 +2912,20 @@ class UdpSource: public virtual Source, public virtual UdpCommon
         bytevector data(chunk);
         sockaddr_any sa(sadr.family());
         int64_t srctime = 0;
+AGAIN:
         int stat = recvfrom(m_sock, data.data(), (int) chunk, 0, sa.get(), &sa.syslen());
+        int err = SysError();
         if (transmit_use_sourcetime)
         {
             srctime = srt_time_now();
         }
         if (stat == -1)
+        {
+            if (!::transmit_int_state && err == SysAGAIN)
+                goto AGAIN;
+
             Error(SysError(), "UDP Read/recvfrom");
+        }
 
         if (stat < 1)
         {