Add r2h-ifname parameter support for RTSP, HTTP proxy, and multicast; rename ifname to r2h-ifname#378
Add r2h-ifname parameter support for RTSP, HTTP proxy, and multicast; rename ifname to r2h-ifname#378
Conversation
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://thankful-water-0a297bf00-378.eastasia.1.azurestaticapps.net |
Co-authored-by: stackia <5107241+stackia@users.noreply.github.com>
Co-authored-by: stackia <5107241+stackia@users.noreply.github.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://thankful-water-0a297bf00-378.eastasia.1.azurestaticapps.net |
… add r2h-ifname-fcc for FCC Co-authored-by: stackia <5107241+stackia@users.noreply.github.com>
…rd declaration Co-authored-by: stackia <5107241+stackia@users.noreply.github.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://thankful-water-0a297bf00-378.eastasia.1.azurestaticapps.net |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8d7ce3507f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| http_parse_query_param(query_start + 1, "r2h-ifname", ifname_value, | ||
| sizeof(ifname_value)); |
There was a problem hiding this comment.
Strip r2h-ifname from proxied HTTP query strings
This path parses r2h-ifname into result->ifname but never removes it from result->http_url; the subsequent service_extract_seek_params(...) call only strips seek-related parameters. When clients use ?r2h-ifname=..., the proxy forwards that internal control parameter upstream, which can break backends that require an exact query string (for example signed URLs or strict parameter validation).
Useful? React with 👍 / 👎.
| http_parse_query_param(query_start + 1, "r2h-ifname", ifname_value, | ||
| sizeof(ifname_value)); |
There was a problem hiding this comment.
Remove r2h-ifname before constructing RTSP upstream URL
The RTSP parser now reads r2h-ifname but leaves it in url_part before building result->rtsp_url, so this internal routing flag is sent to the upstream RTSP server as part of the request URI. This can cause stream setup failures on servers that do not ignore unknown query parameters, specifically whenever per-URL interface selection is used.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds per-URL upstream interface selection via new query parameters (r2h-ifname, r2h-ifname-fcc) so different streams can be bound to different NICs without changing global config.
Changes:
- Extend
service_tto carry per-service interface overrides and clone/free them correctly. - Parse
r2h-ifname/r2h-ifname-fccfrom RTP/RTSP/HTTP URLs and prefer them over global upstream-interface settings when binding sockets. - Update Chinese and English URL format documentation with the new parameters and examples.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/stream.c | Passes service into HTTP proxy connect and attaches service to RTSP session for per-service config access. |
| src/service.h | Adds per-service interface override fields (ifname, ifname_fcc). |
| src/service.c | Parses interface query params; stores/clones/frees them on services. |
| src/rtsp.h | Adds service_t* to RTSP session for per-service interface selection. |
| src/rtsp.c | Uses per-service interface (if set) when binding RTSP TCP/UDP sockets. |
| src/multicast.c | Uses per-service interface (if set) when joining/binding multicast sockets. |
| src/http_proxy.h | Updates http_proxy_connect signature to accept optional service. |
| src/http_proxy.c | Uses per-service interface (if set) when binding HTTP proxy upstream socket. |
| src/fcc.c | Uses per-service FCC interface (if set) when binding FCC socket. |
| docs/guide/url-formats.md | Documents r2h-ifname and r2h-ifname-fcc in CN guide. |
| docs/en/guide/url-formats.md | Documents r2h-ifname and r2h-ifname-fcc in EN guide. |
Comments suppressed due to low confidence (1)
src/service.c:918
service_create_from_rtsp_url()extractsr2h-ifnamefor local binding but does not remove it fromurl_partbefore buildingresult->rtsp_url. That means the RTSP server will receiver2h-ifnameas part of the RTSP request URI, which can cause upstream incompatibilities. Stripr2h-ifnamefrom the query string (similar to the seek param removal) after parsing it.
/* Extract seek parameters from query string (modifies url_part in-place) */
query_start = strchr(url_part, '?');
if (query_start) {
/* Extract r2h-ifname parameter before processing seek params */
http_parse_query_param(query_start + 1, "r2h-ifname", ifname_value,
sizeof(ifname_value));
if (service_extract_seek_params(query_start, &seek_param_name,
&seek_param_value,
&seek_offset_seconds) < 0) {
return NULL;
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /* Use per-service interface if specified, otherwise use global config */ | ||
| if (service && service->ifname && service->ifname[0] != '\0') { | ||
| upstream_if = service->ifname; | ||
| } else { | ||
| upstream_if = get_upstream_interface_for_http(); | ||
| } |
There was a problem hiding this comment.
http_proxy_connect() now dereferences service->ifname, but http_proxy.c only sees service_t as a forward declaration via http_proxy.h. This will not compile (incomplete type) unless you include service.h in http_proxy.c (or otherwise provide the full service_t definition) before accessing its fields.
| char ifname_value[IFNAMSIZ] = {0}; | ||
| http_parse_query_param(query_start + 1, "r2h-ifname", ifname_value, | ||
| sizeof(ifname_value)); | ||
|
|
There was a problem hiding this comment.
service_create_from_http_url() extracts r2h-ifname but does not remove it from result->http_url. Since the HTTP proxy forwards target_path (including query string) upstream, this internal control parameter will be sent to the upstream server and may break requests. Consider stripping r2h-ifname from the stored URL similarly to how service_extract_seek_params() removes r2h-seek-* params.
| /* Strip r2h-ifname from the stored HTTP URL so it is not forwarded upstream */ | |
| { | |
| const char *orig_query = query_start + 1; | |
| char new_query[HTTP_URL_BUFFER_SIZE] = {0}; | |
| size_t new_len = 0; | |
| int first_param = 1; | |
| const char *read = orig_query; | |
| while (*read) { | |
| const char *param_start = read; | |
| const char *param_end = strchr(read, '&'); | |
| if (!param_end) { | |
| param_end = read + strlen(read); | |
| } | |
| /* Determine parameter name and check if it is r2h-ifname */ | |
| const char *eq = memchr(param_start, '=', (size_t)(param_end - param_start)); | |
| int is_ifname_param = 0; | |
| if (eq) { | |
| size_t name_len = (size_t)(eq - param_start); | |
| static const char ifname_key[] = "r2h-ifname"; | |
| if (name_len == (sizeof(ifname_key) - 1) && | |
| strncmp(param_start, ifname_key, name_len) == 0) { | |
| is_ifname_param = 1; | |
| } | |
| } | |
| if (!is_ifname_param) { | |
| if (!first_param) { | |
| if (new_len + 1 >= sizeof(new_query)) { | |
| break; | |
| } | |
| new_query[new_len++] = '&'; | |
| } | |
| size_t copy_len = (size_t)(param_end - param_start); | |
| if (new_len + copy_len >= sizeof(new_query)) { | |
| break; | |
| } | |
| memcpy(new_query + new_len, param_start, copy_len); | |
| new_len += copy_len; | |
| first_param = 0; | |
| } | |
| if (*param_end == '&') { | |
| read = param_end + 1; | |
| } else { | |
| break; | |
| } | |
| } | |
| new_query[new_len] = '\0'; | |
| /* Rebuild result->http_url without the r2h-ifname parameter */ | |
| { | |
| size_t prefix_len = (size_t)(query_start - result->http_url); | |
| if (new_len == 0) { | |
| /* No query parameters remain; terminate the string at '?' */ | |
| result->http_url[prefix_len] = '\0'; | |
| } else { | |
| result->http_url[prefix_len] = '?'; | |
| memcpy(result->http_url + prefix_len + 1, new_query, new_len + 1); | |
| } | |
| /* refresh query_start pointer in case the underlying buffer moved logically */ | |
| query_start = strchr(result->http_url, '?'); | |
| } | |
| } |
| free(result->url); | ||
| free(result->http_url); | ||
| free(result); |
There was a problem hiding this comment.
On strdup(ifname_value) failure, this function frees result, result->url, and result->http_url, but it does not free any seek-related allocations that may have been created by service_extract_seek_params() earlier in this block. Using service_free(result) (or explicitly freeing seek_param_name/seek_param_value) on this path will avoid leaking memory.
| free(result->url); | |
| free(result->http_url); | |
| free(result); | |
| service_free(result); |
Original prompt