Repository navigation
Conversation
- raop_ntp.c: the fallback recvfrom() in kernel_timestamp_session_recv() passed &addrlen (the address of the int* parameter) instead of addrlen. When a source address is requested, Windows rejects the call with WSAEFAULT (10014). The RTP control socket requests it until its first successful read, so no control packets (sync, resent audio) were ever received and AAC-ELD mirror audio was silent. - raop_rtp.c: packetlen was unsigned, so a -1 return from a failed recv became ~4 billion and was processed as a valid packet. Make it signed; skip failed control-socket reads (logging the socket error), and don't hex-dump failed data-socket reads in debug mode. - netutils.c (defensive): disable SIO_UDP_CONNRESET on Windows UDP sockets, so ICMP port-unreachable replies don't surface as WSAECONNRESET errors on later reads.
|
Confirming this on a second, independent setup: same bug, and the same fix works. Setup: UxPlay 1.74 at ec20312, MSYS2 UCRT64 (gcc 16.2.0, GStreamer 1.28.8), Before: video fine, no audio. The first control packet (read through After, with a patch functionally equivalent to this PR ( I also built this PR as-is (85034dc on top of ec20312) with the toolchain above: it builds cleanly, with no Minimal reproducer, no AirPlay client needed. It makes the same /* gcc repro.c -o repro.exe -lws2_32 */
#include <winsock2.h>
#include <stdio.h>
int main(void) {
WSADATA w; WSAStartup(MAKEWORD(2, 2), &w);
SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in a = { .sin_family = AF_INET };
a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
bind(s, (struct sockaddr *) &a, sizeof(a));
int len = sizeof(a); getsockname(s, (struct sockaddr *) &a, &len);
char buf[2048], pkt[300] = {0x80, 0x60};
sendto(s, pkt, sizeof(pkt), 0, (struct sockaddr *) &a, sizeof(a));
int *addrlen = NULL; /* as called from raop_rtp.c: src_addr = NULL, addrlen = NULL */
for (int i = 0; i < 2; i++) {
int n = recvfrom(s, buf, sizeof(buf), 0, NULL, (int *) &addrlen); /* current code */
printf("recvfrom(..., NULL, &addrlen) = %d, WSAGetLastError() = %d\n", n, n < 0 ? WSAGetLastError() : 0);
}
int n = recvfrom(s, buf, sizeof(buf), 0, NULL, addrlen); /* fixed code */
printf("recvfrom(..., NULL, addrlen) = %d\n", n);
return 0;
}So the This PR should also fix #605, which reports the same bug. Thanks for UxPlay! |
|
This is now fixed (hopefully) It was a recent code error that slipped in. Fix is PLEASE REPORT BACK IF THERE IS STILL AN ERROR! |
Problem
On Windows (MSYS2 UCRT64 build), screen mirroring from an iPad shows video
but plays no audio.
Cause
In
kernel_timestamp_session_recv()(lib/raop_ntp.c), the fallbackrecvfrom()passes&addrlen— the address of theint *addrlenparameter — instead of
addrlen. When the caller requests the sourceaddress, Windows rejects the call with WSAEFAULT (10014). The RTP control
socket requests the source address until its first successful read, so it
never receives anything: no sync packets and no resent audio, and the
AAC-ELD mirror audio stays silent.
Because
packetleninraop_rtp_thread_udp()wasunsigned int, the -1return was also treated as a ~4 GB packet instead of an error (and in
debug mode it triggered
assert(datalen >= 0)in utils.c).Changes
addrleninstead of&addrlentorecvfrom()(both the Windows and POSIX branches).
packetlensigned; skip failed control-socketreads (logging the socket error); don't hex-dump failed data-socket
reads in debug mode.
sockets so ICMP port-unreachable replies don't surface as WSAECONNRESET
on later reads.
Testing
Windows 11, MSYS2 UCRT64 (GStreamer 1.26.9), built with
-DUSE_DNS_SD=1,mirroring from an iPad: audio was silent before the fix and plays
correctly after it. Not tested on Linux or macOS.