Add support for X-SS-Connect-Data in RTSP SETUP for control stream

This allows the host to provide a 32-bit integer that will be sent
in the data of the ENet connect event, similar to X-SS-Ping-Payload
for video and audio.

The host can use this data to uniquely identify a client when IP
addresses are not stable across the various separate connections,
such as when the client is behind a Carrier-Grade NAT.
This commit is contained in:
Cameron Gutman
2023-12-28 16:56:06 -06:00
parent 50d8dcb072
commit 6e9ed871bc
5 changed files with 15 additions and 2 deletions

View File

@@ -31,6 +31,7 @@ uint16_t AudioPortNumber;
uint16_t VideoPortNumber;
SS_PING AudioPingPayload;
SS_PING VideoPingPayload;
uint32_t ControlConnectData;
uint32_t SunshineFeatureFlags;
// Connection stages

View File

@@ -1625,7 +1625,7 @@ int startControlStream(void) {
enet_socket_set_option (client->socket, ENET_SOCKOPT_QOS, 1);
// Connect to the host
peer = enet_host_connect(client, &remoteAddress, CTRL_CHANNEL_COUNT, 0);
peer = enet_host_connect(client, &remoteAddress, CTRL_CHANNEL_COUNT, ControlConnectData);
if (peer == NULL) {
stopping = true;
enet_host_destroy(client);

View File

@@ -40,6 +40,7 @@ extern uint16_t VideoPortNumber;
extern SS_PING AudioPingPayload;
extern SS_PING VideoPingPayload;
extern uint32_t ControlConnectData;
extern uint32_t SunshineFeatureFlags;
@@ -76,6 +77,7 @@ extern uint32_t SunshineFeatureFlags;
// Client feature flags for x-ml-general.featureFlags SDP attribute
#define ML_FF_FEC_STATUS 0x01 // Client sends SS_FRAME_FEC_STATUS for frame losses
#define ML_FF_SESSION_ID_V1 0x02 // Client supports X-SS-Ping-Payload and X-SS-Connect-Data
#define UDP_RECV_POLL_TIMEOUT_MS 100

View File

@@ -1067,6 +1067,7 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) {
if (AppVersionQuad[0] >= 5) {
RTSP_MESSAGE response;
int error = -1;
char* connectData;
if (!setupStream(&response,
controlStreamId,
@@ -1083,6 +1084,15 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) {
goto Exit;
}
// Parse the Sunshine control connect data extension if present
connectData = getOptionContent(response.options, "X-SS-Connect-Data");
if (connectData != NULL) {
ControlConnectData = (uint32_t)strtoul(connectData, NULL, 0);
}
else {
ControlConnectData = 0;
}
// Parse the control port out of the RTSP SETUP response
LC_ASSERT(ControlPortNumber == 0);
if (!parseServerPortFromTransport(&response, &ControlPortNumber)) {

View File

@@ -268,7 +268,7 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
// Send client feature flags to Sunshine hosts
if (IS_SUNSHINE()) {
uint32_t moonlightFeatureFlags = ML_FF_FEC_STATUS;
uint32_t moonlightFeatureFlags = ML_FF_FEC_STATUS | ML_FF_SESSION_ID_V1;
snprintf(payloadStr, sizeof(payloadStr), "%u", moonlightFeatureFlags);
err |= addAttributeString(&optionHead, "x-ml-general.featureFlags", payloadStr);
}