Feature #4617

SAT>IP: Support different PORT over NAT FORWARDING

Added by Mono Polimorph about 1 month ago. Updated 13 days ago.

Status:FixedStart date:2017-09-21
Priority:NormalDue date:
Assignee:Jaroslav Kysela% Done:

100%

Category:SAT>IP
Target version:-

Description

Hi,

With the current implementation of the SAT>IP, when the server is over a NAT router it's required that the external port be the same as the internal port. This can be possible if you have control over the router. However, this is not always possible.

This patch resolves this problem. It enables the option for use a Custom External PORT. This concerns only to RTSP commands that use the server port (like do now the NAT external IP parameter already implemented).

Here the patch:

diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c
index e194bcc..a4a99e3 100644
--- a/src/satip/rtsp.c
+++ b/src/satip/rtsp.c
@@ -81,6 +81,7 @@ static uint16_t stream_id;
 static char *rtsp_ip = NULL;
 static char *rtsp_nat_ip = NULL;
 static int rtsp_port = -1;
+static int rtsp_nat_port = -1;
 static int rtsp_descramble = 1;
 static int rtsp_rewrite_pmt = 0;
 static int rtsp_muxcnf = MUXCNF_AUTO;
@@ -252,6 +253,7 @@ static char *
 rtsp_check_urlbase(char *u)
 {
   char *p, *s;
+  int t;

   if (*u == '/' || strncmp(u, "stream=", 7) == 0)
     return u;
@@ -264,7 +266,8 @@ rtsp_check_urlbase(char *u)
     *p = '\0';
   if ((s = strchr(u, ':')) != NULL) {
     *s = '\0';
-    if (atoi(s + 1) != rtsp_port)
+    t = rtsp_nat_port ?: rtsp_port;
+    if (atoi(s + 1) != t)
       return NULL;
   } else {
 #if 0 /* VLC is broken */
@@ -1393,7 +1396,7 @@ static int
 rtsp_process_play(http_connection_t *hc, int cmd)
 {
   session_t *rs;
-  int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, stream;
+  int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, p, stream;
   char buf[256], *u = tvh_strdupa(hc->hc_url);
   http_arg_list_t args;

@@ -1452,8 +1455,9 @@ rtsp_process_play(http_connection_t *hc, int cmd)
     snprintf(buf, sizeof(buf), "%d", rs->stream);
     http_arg_set(&args, "com.ses.streamID", buf);
   } else {
-    if (rtsp_port != 554)
-      snprintf(buf, sizeof(buf), "url=rtsp://%s:%d/stream=%d", rtsp_ip, rtsp_port, rs->stream);
+    p = rtsp_nat_port ?: rtsp_port;
+    if (p != 554)
+      snprintf(buf, sizeof(buf), "url=rtsp://%s:%d/stream=%d", rtsp_ip, p, rs->stream);
     else
       snprintf(buf, sizeof(buf), "url=rtsp://%s/stream=%d", rtsp_ip, rs->stream);
     http_arg_set(&args, "RTP-Info", buf);
@@ -1683,7 +1687,7 @@ rtsp_close_sessions(void)
  */
 void satip_server_rtsp_init
   (const char *bindaddr, int port, int descramble, int rewrite_pmt, int muxcnf,
-   const char *nat_ip)
+   const char *nat_ip, int nat_port)
 {
   static tcp_server_ops_t ops = {
     .start  = rtsp_serve,
@@ -1716,6 +1720,7 @@ void satip_server_rtsp_init
   s = rtsp_nat_ip;
   rtsp_nat_ip = nat_ip ? strdup(nat_ip) : NULL;
   free(s);
+  rtsp_nat_port = nat_port;
   if (!rtsp_server)
     rtsp_server = tcp_server_create(LS_SATIPS, "SAT>IP RTSP", bindaddr, port, &ops, NULL);
   if (reg)
@@ -1738,6 +1743,7 @@ void satip_server_rtsp_done(void)
   pthread_mutex_lock(&global_lock);
   rtsp_server = NULL;
   rtsp_port = -1;
+  rtsp_nat_port = -1;
   free(rtsp_ip);
   free(rtsp_nat_ip);
   rtsp_ip = rtsp_nat_ip = NULL;
diff --git a/src/satip/server.c b/src/satip/server.c
index e6b5fdf..90b28fe 100644
--- a/src/satip/server.c
+++ b/src/satip/server.c
@@ -754,6 +754,16 @@ const idclass_t satip_server_class = {
       .group  = 1,
     },
     {
+      .type   = PT_INT,
+      .id     = "satip_nat_rtsp",
+      .name   = N_("External RTSP port (NAT)"),
+      .desc   = N_("Enter external PORT if behind Forwarding redirection." 
+                   "(0 = use the same local port)."),
+      .off    = offsetof(struct satip_server_conf, satip_nat_rtsp),
+      .opts   = PO_EXPERT,
+      .group  = 1,
+    },
+    {
       .type   = PT_BOOL,
       .id     = "satip_nom3u",
       .name   = N_("Disable X_SATIPM3U tag"),
@@ -868,6 +878,7 @@ static void satip_server_init_common(const char *prefix, int announce)
   char http_ip[128];
   int descramble, rewrite_pmt, muxcnf;
   char *nat_ip;
+  int nat_port;

   if (satip_server_rtsp_port <= 0)
     return;
@@ -890,13 +901,14 @@ static void satip_server_init_common(const char *prefix, int announce)
   rewrite_pmt = satip_server_conf.satip_rewrite_pmt;
   muxcnf = satip_server_conf.satip_muxcnf;
   nat_ip = strdup(satip_server_conf.satip_nat_ip ?: "");
+  nat_port = satip_server_conf.satip_nat_rtsp ?: satip_server_rtsp_port;

   if (announce)
     pthread_mutex_unlock(&global_lock);

   pthread_mutex_lock(&satip_server_reinit);

-  satip_server_rtsp_init(http_server_ip, satip_server_rtsp_port, descramble, rewrite_pmt, muxcnf, nat_ip);
+  satip_server_rtsp_init(http_server_ip, satip_server_rtsp_port, descramble, rewrite_pmt, muxcnf, nat_ip, nat_port);
   satip_server_info(prefix, descramble, muxcnf);

   if (announce)
diff --git a/src/satip/server.h b/src/satip/server.h
index 054e481..bb23271 100644
--- a/src/satip/server.h
+++ b/src/satip/server.h
@@ -62,6 +62,7 @@ struct satip_server_conf {
   int satip_atsc_t;
   int satip_atsc_c;
   char *satip_nat_ip;
+  int satip_nat_rtsp;
 };

 extern struct satip_server_conf satip_server_conf;
@@ -92,7 +93,7 @@ int satip_rtsp_delsys(int fe, int *findex, const char **ftype);

 void satip_server_rtsp_init(const char *bindaddr, int port,
                             int descramble, int rewrite_pmt, int muxcnf,
-                            const char *nat_ip);
+                            const char *nat_ip, int nat_port);
 void satip_server_rtsp_register(void);
 void satip_server_rtsp_done(void);

I hope you agree to commit it, as it completes the support for all NAT scenarios.
Attached is the patch file for easy apply. (I'm sorry, I can't produce a GitHub PR at time!)

Regards.

SAT-IP-NAT-port-support.diff Magnifier - Patch (4.83 KB) Mono Polimorph, 2017-09-21 13:27

Associated revisions

Revision f8f018e9
Added by Jaroslav Kysela 13 days ago

satip server: Support different PORT over NAT FORWARDING, fixes #4617

From: Mono Polimorph

Revision 07f80d03
Added by Jaroslav Kysela 13 days ago

satip server: Support different PORT over NAT FORWARDING, fixes #4617

From: Mono Polimorph

History

#1 Updated by Mono Polimorph 27 days ago

Hi Jaroslav,

Please, commit this patch,too . Very usefull! I'm using it right now.

#2 Updated by Mono Polimorph 20 days ago

Still waiting for the acceptance of this patch. ;)

#3 Updated by Mono Polimorph 13 days ago

I hope this patch will be accepted.
If there is something to change, please tell me what I have to do. ;)

#4 Updated by Jaroslav Kysela 13 days ago

  • Status changed from New to Fixed
  • % Done changed from 0 to 100

#5 Updated by Mono Polimorph 13 days ago

Thank you!

However, a slight difference in the implementation.

You overcome this part of the patch:

@@ -1393,7 +1396,7 @@ static int
 rtsp_process_play(http_connection_t *hc, int cmd)
 {
   session_t *rs;
-  int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, stream;
+  int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, p, stream;
   char buf[256], *u = tvh_strdupa(hc->hc_url);
   http_arg_list_t args;

@@ -1452,8 +1455,9 @@ rtsp_process_play(http_connection_t *hc, int cmd)
     snprintf(buf, sizeof(buf), "%d", rs->stream);
     http_arg_set(&args, "com.ses.streamID", buf);
   } else {
-    if (rtsp_port != 554)
-      snprintf(buf, sizeof(buf), "url=rtsp://%s:%d/stream=%d", rtsp_ip, rtsp_port, rs->stream);
+    p = rtsp_nat_port ?: rtsp_port;
+    if (p != 554)
+      snprintf(buf, sizeof(buf), "url=rtsp://%s:%d/stream=%d", rtsp_ip, p, rs->stream);
     else
       snprintf(buf, sizeof(buf), "url=rtsp://%s/stream=%d", rtsp_ip, rs->stream);
     http_arg_set(&args, "RTP-Info", buf);
@@ -1683,7 +1687,7 @@ rtsp_close_sessions(void)

If you don't catch this, the client can be confused: You indicate the real listening RTSP port, but the user connects to the NAT port.
Why you don't like this part of the patch?

Regards.

#6 Updated by Jaroslav Kysela 13 days ago

I think that most clients does not parse this info and we use only the local IP address here (rtsp_ip not rtsp_nat_ip), too. The correct implementation should be to detect the "external" connection and masquearade everything for it, but this requires to specify the internal IP ranges from user (routed) and gather the IP networks bound to the local ethernet adapters.

#7 Updated by Mono Polimorph 13 days ago

Jaroslav Kysela wrote:

I think that most clients does not parse this info and we use only the local IP address here (rtsp_ip not rtsp_nat_ip), too. The correct implementation should be to detect the "external" connection and masquearade everything for it, but this requires to specify the internal IP ranges from user (routed) and gather the IP networks bound to the local ethernet adapters.

Hi,

I don't understand it! This piece of code if for use the NAT port instead of the listening port. Equal as you use the NAT address, you need to use the NAT port!

rtsp_ip is the NAT address if you use NAT, and the local address if the NAT is disabled.
rtsp_port is all the time the listening port.
rtsp_nat_port is the NAT port if the NAT is enabled.

So you have all the required data in the function! You only need to use "rtsp_port" if NAT is disabled, and "rtsp_nat_port" if NAT is enabled.

The patch is fully tested. So please, commit also this part. Without it some clients will refuse to connect.
Thank you!

#8 Updated by Jaroslav Kysela 13 days ago

Mono Polimorph wrote:

Jaroslav Kysela wrote:

I think that most clients does not parse this info and we use only the local IP address here (rtsp_ip not rtsp_nat_ip), too. The correct implementation should be to detect the "external" connection and masquearade everything for it, but this requires to specify the internal IP ranges from user (routed) and gather the IP networks bound to the local ethernet adapters.

Hi,

I don't understand it! This piece of code if for use the NAT port instead of the listening port. Equal as you use the NAT address, you need to use the NAT port!

rtsp_ip is the NAT address if you use NAT, and the local address if the NAT is disabled.

It's your mistake. rtsp_ip is the bind IP (local IP). Always.

#9 Updated by Mono Polimorph 13 days ago

Jaroslav Kysela wrote:

It's your mistake. rtsp_ip is the bind IP (local IP). Always.

Ah! Ok, thank you for pointing it!

So, I'll rewrite the patch for use both the NAT IP & NAT PORT when advertizing.

Regards.

Also available in: Atom PDF