]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Remove 8.8.8.8 and instead determine the local IP for each packet remove8888 1637/head
authorFlole998 <Flole998@users.noreply.github.com>
Fri, 9 Feb 2024 22:12:42 +0000 (22:12 +0000)
committerFlole <Flole998@users.noreply.github.com>
Sun, 25 May 2025 11:16:00 +0000 (13:16 +0200)
src/input/mpegts/satip/satip.c
src/satip/rtsp.c
src/satip/server.c
src/tcp.c
src/tcp.h
src/udp.c
src/udp.h
src/upnp.c
src/upnp.h

index 58e91d30bb016fb265ff081a644f157aeed5b9da..e4ecc34c621837e41f1e36adb30f1224a4f45e19 100644 (file)
@@ -1306,7 +1306,7 @@ ST: urn:ses-com:device:SatIPServer:1\r\n"
   htsbuf_append(&q, MSG, sizeof(MSG)-1);
   htsbuf_qprintf(&q, "USER-AGENT: unix/1.0 UPnP/1.1 tvheadend/%s\r\n", tvheadend_version);
   htsbuf_append(&q, "\r\n", 2);
-  upnp_send(&q, NULL, 0, 0);
+  upnp_send(&q, NULL, 0, 0, 0);
   htsbuf_queue_flush(&q);
 
   mtimer_arm_rel(&satip_discovery_msearch_timer, satip_discovery_send_msearch,
index 24efae9d792c0a1e66deb84eb7d5514ca6b9fc74..239aa4d4348ebf4fda28188727aa0188ec023307 100644 (file)
@@ -1889,7 +1889,8 @@ void satip_server_rtsp_init
     reg = 1;
   }
   s = rtsp_ip;
-  rtsp_ip = strdup(bindaddr);
+  if(bindaddr != NULL)
+    rtsp_ip = strdup(bindaddr);
   free(s);
   rtsp_port = port;
   rtsp_descramble = descramble;
index 401fd6b63ab386ed8f6814f25ffa754349c28e02..19f274ce0f7127665c0a4190a39148b2981e4e31 100644 (file)
@@ -114,6 +114,7 @@ satip_server_http_xml(http_connection_t *hc)
 
   char buf[sizeof(MSG) + 1024], buf2[64], purl[128];
   const char *cs;
+  char addrbuf[50];
   char *devicelist = NULL;
   htsbuf_queue_t q;
   mpegts_network_t *mn;
@@ -135,7 +136,7 @@ satip_server_http_xml(http_connection_t *hc)
     {}
   };
 
-  if (http_server_ip == NULL)
+  if (http_server_port == 0)
     return HTTP_STATUS_NOT_FOUND;
 
   htsbuf_queue_init(&q, 0);
@@ -222,15 +223,22 @@ satip_server_http_xml(http_connection_t *hc)
              tvheadend_webroot ?: "", cs);
   }
 
+  char* own_server_ip = http_server_ip;
+
+  if(own_server_ip == NULL) {
+    tcp_get_str_from_ip(hc->hc_self, addrbuf, sizeof(addrbuf));
+    own_server_ip = addrbuf;
+  } 
+
   snprintf(buf, sizeof(buf), MSG,
            config_get_server_name(),
            buf2, tvheadend_version,
            satip_server_conf.satip_uuid,
-           http_server_ip, http_server_port,
-           http_server_ip, http_server_port,
-           http_server_ip, http_server_port,
-           http_server_ip, http_server_port,
-           http_server_ip, http_server_port,
+           own_server_ip, http_server_port,
+           own_server_ip, http_server_port,
+           own_server_ip, http_server_port,
+           own_server_ip, http_server_port,
+           own_server_ip, http_server_port,
            devicelist ?: "", purl);
 
   free(devicelist);
@@ -327,7 +335,7 @@ CONFIGID.UPNP.ORG: 0\r\n\
 
     htsbuf_queue_init(&q, 0);
     htsbuf_append_str(&q, buf);
-    upnp_send(&q, NULL, attempt * 11, 1);
+    upnp_send(&q, NULL, attempt * 11, 1, 0);
     htsbuf_queue_flush(&q);
   }
 #undef MSG
@@ -378,15 +386,17 @@ DEVICEID.SES.COM: %d\r\n\r\n"
       abort();
     }
 
+    char* own_server_ip = http_server_ip;
+
     snprintf(buf, sizeof(buf), MSG, UPNP_MAX_AGE,
-             http_server_ip, http_server_port, tvheadend_webroot ?: "",
+             own_server_ip ?: "%s", http_server_port, tvheadend_webroot ?: "",
              nt, tvheadend_version,
              satip_server_conf.satip_uuid, usn2, (long)satip_server_bootid,
              satip_server_deviceid);
 
     htsbuf_queue_init(&q, 0);
     htsbuf_append_str(&q, buf);
-    upnp_send(&q, NULL, attempt * 11, 1);
+    upnp_send(&q, NULL, attempt * 11, 1, own_server_ip == NULL);
     htsbuf_queue_flush(&q);
   }
 #undef MSG
@@ -420,8 +430,10 @@ CONFIGID.UPNP.ORG: 0\r\n"
              buf, ntohs(IP_PORT(*dst)), deviceid ? " device: " : "", deviceid ?: "");
   }
 
+  char* own_server_ip = http_server_ip;
+
   snprintf(buf, sizeof(buf), MSG, UPNP_MAX_AGE,
-           http_server_ip, http_server_port, tvheadend_webroot ?: "",
+           own_server_ip ?: "%s", http_server_port, tvheadend_webroot ?: "",
            tvheadend_version,
            satip_server_conf.satip_uuid, (long)satip_server_bootid);
 
@@ -431,7 +443,7 @@ CONFIGID.UPNP.ORG: 0\r\n"
     htsbuf_qprintf(&q, "DEVICEID.SES.COM: %s", deviceid);
   htsbuf_append(&q, "\r\n", 2);
   storage = *dst;
-  upnp_send(&q, &storage, 0, from_multicast);
+  upnp_send(&q, &storage, 0, from_multicast, own_server_ip == NULL);
   htsbuf_queue_flush(&q);
 #undef MSG
 }
@@ -517,7 +529,7 @@ satips_upnp_discovery_received
     return;
   if (conn->multicast && strcmp(argv[0], "239.255.255.250"))
     return;
-  if (!conn->multicast && strcmp(argv[0], http_server_ip))
+  if (!conn->multicast && http_server_ip != NULL && strcmp(argv[0], http_server_ip))
     return;
 
   if (tvhtrace_enabled()) {
@@ -584,8 +596,8 @@ static void satip_server_info(const char *prefix, int descramble, int muxcnf)
   }
   tvhinfo(LS_SATIPS, "SAT>IP Server %sinitialized", prefix);
   tvhinfo(LS_SATIPS, "  HTTP %s:%d, RTSP %s:%d",
-              http_server_ip, http_server_port,
-              http_server_ip, satip_server_rtsp_port);
+              http_server_ip ?: "0.0.0.0", http_server_port,
+              http_server_ip ?: "0.0.0.0", satip_server_rtsp_port);
   tvhinfo(LS_SATIPS, "  descramble %d, muxcnf %d",
               descramble, muxcnf);
   for (fe = 1; fe <= 128; fe++) {
@@ -979,8 +991,6 @@ const idclass_t satip_server_class = {
  */
 static void satip_server_init_common(const char *prefix, int announce)
 {
-  struct sockaddr_storage http;
-  char http_ip[128];
   int descramble, rewrite_pmt, muxcnf;
   char *nat_ip, *rtp_src_ip;
   int nat_port;
@@ -988,18 +998,10 @@ static void satip_server_init_common(const char *prefix, int announce)
   if (satip_server_rtsp_port <= 0)
     return;
 
-  if (http_server_ip == NULL) {
-    if (tcp_server_onall(http_server) && satip_server_bindaddr == NULL) {
-      tvherror(LS_SATIPS, "use --satip_bindaddr parameter to select the local IP for SAT>IP");
-      tvherror(LS_SATIPS, "using Google lookup (might block the task until timeout)");
-    }
-    if (tcp_server_bound(http_server, &http, PF_INET) < 0) {
-      tvherror(LS_SATIPS, "Unable to determine the HTTP/RTSP address");
-      return;
-    }
-    tcp_get_str_from_ip(&http, http_ip, sizeof(http_ip));
-    http_server_ip = strdup(satip_server_bindaddr ?: http_ip);
-    http_server_port = ntohs(IP_PORT(http));
+  if (http_server_port == 0) {
+    http_server_ip = satip_server_bindaddr ? strdup(satip_server_bindaddr) : NULL;
+    tcp_server_t* srv = http_server;
+    http_server_port = ntohs(IP_PORT(srv->bound));
   }
 
   descramble = satip_server_conf.satip_descramble;
@@ -1082,7 +1084,7 @@ void satip_server_register(void)
   tvh_uuid_t u;
   int save = 0;
 
-  if (http_server_ip == NULL)
+  if (http_server_port == 0)
     return;
 
   if (satip_server_conf.satip_rtsp != satip_server_rtsp_port) {
@@ -1142,6 +1144,7 @@ void satip_server_done(void)
   satip_server_rtsp_port = 0;
   free(http_server_ip);
   http_server_ip = NULL;
+  http_server_port = 0;
   free(satip_server_conf.satip_uuid);
   satip_server_conf.satip_uuid = NULL;
   free(satip_server_bindaddr);
index 8ff5587301cfe57cd2815e3ba16df75def8f12de..bc11b46da7225ad5e716c0de4572ed09120194e1 100644 (file)
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -509,31 +509,6 @@ tcp_get_ip_from_str(const char *src, struct sockaddr_storage *sa)
 static tvhpoll_t *tcp_server_poll;
 static uint32_t tcp_server_launch_id;
 
-typedef struct tcp_server {
-  int serverfd;
-  struct sockaddr_storage bound;
-  tcp_server_ops_t ops;
-  void *opaque;
-  LIST_ENTRY(tcp_server) link;
-} tcp_server_t;
-
-typedef struct tcp_server_launch {
-  pthread_t tid;
-  uint32_t id;
-  int fd;
-  int streaming;
-  tcp_server_ops_t ops;
-  void *opaque;
-  char *representative;
-  void (*status) (void *opaque, htsmsg_t *m);
-  struct sockaddr_storage peer;
-  struct sockaddr_storage self;
-  time_t started;
-  LIST_ENTRY(tcp_server_launch) link;
-  LIST_ENTRY(tcp_server_launch) alink;
-  LIST_ENTRY(tcp_server_launch) jlink;
-} tcp_server_launch_t;
-
 static LIST_HEAD(, tcp_server) tcp_server_delete_list = { 0 };
 static LIST_HEAD(, tcp_server_launch) tcp_server_launches = { 0 };
 static LIST_HEAD(, tcp_server_launch) tcp_server_active = { 0 };
index 5d32b892656a974df9cdc1b30886c103549e8d41..28d59c68ef676e10d10b596f929faa79902e3fc0 100644 (file)
--- a/src/tcp.h
+++ b/src/tcp.h
@@ -56,6 +56,31 @@ typedef struct tcp_server_ops
   void (*cancel) (void *opaque);
 } tcp_server_ops_t;
 
+typedef struct tcp_server {
+  int serverfd;
+  struct sockaddr_storage bound;
+  tcp_server_ops_t ops;
+  void *opaque;
+  LIST_ENTRY(tcp_server) link;
+} tcp_server_t;
+
+typedef struct tcp_server_launch {
+  pthread_t tid;
+  uint32_t id;
+  int fd;
+  int streaming;
+  tcp_server_ops_t ops;
+  void *opaque;
+  char *representative;
+  void (*status) (void *opaque, htsmsg_t *m);
+  struct sockaddr_storage peer;
+  struct sockaddr_storage self;
+  time_t started;
+  LIST_ENTRY(tcp_server_launch) link;
+  LIST_ENTRY(tcp_server_launch) alink;
+  LIST_ENTRY(tcp_server_launch) jlink;
+} tcp_server_launch_t;
+
 extern int tcp_preferred_address_family;
 
 void tcp_server_preinit(int opt_ipv6);
index 40cb8308b9d9d319dbcd1c83a0427033dc99c07d..32ca3c5803ab5d61743f0114db796a8be95b37c8 100644 (file)
--- a/src/udp.c
+++ b/src/udp.c
@@ -494,6 +494,98 @@ udp_close( udp_connection_t *uc )
   free(uc);
 }
 
+int
+udp_write_fill_source( udp_connection_t *uc, const void *buf, size_t len,
+                       struct sockaddr_storage *storage)
+{
+    int r;
+    struct sockaddr_in local_addr;
+    socklen_t local_addr_len = sizeof(local_addr);
+    struct sockaddr_in parent_addr;
+    socklen_t parent_addrlen = sizeof(parent_addr);
+    int reuse = 1;
+
+
+    if (storage == NULL)
+      storage = &uc->ip;
+
+    tvhdebug(uc->subsystem, "Got dst IP address: %s", inet_ntoa(((struct sockaddr_in*)storage)->sin_addr));
+
+    // Get the current socket configuration
+    if (getsockname(uc->fd, (struct sockaddr *)&parent_addr, &parent_addrlen) < 0) {
+        perror("getsockname");
+        return -1;
+    }
+    tvhdebug(uc->subsystem, "Got parent IP address: %s", inet_ntoa(parent_addr.sin_addr));
+
+    // Create a new socket
+    int cloned_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (cloned_sockfd < 0) {
+        perror("socket");
+        return -1;
+    }
+
+
+    /* Mark reuse address */
+    if (setsockopt(cloned_sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
+      tvherror(uc->subsystem, "failed to reuse address for socket [%s]", strerror(errno));
+      close(cloned_sockfd);
+      return -1;
+    }
+
+    // Set the address to INADDR_ANY to let the routing table choose the source IP
+    parent_addr.sin_addr.s_addr = INADDR_ANY;
+
+    // Bind the new socket to the same port
+    if (bind(cloned_sockfd, (struct sockaddr *)&parent_addr, parent_addrlen) < 0) {
+        tvherror(uc->subsystem, "failed to bind address for socket [%s]", strerror(errno));
+        close(cloned_sockfd);
+        return -1;
+    }
+
+    // Connect the socket to the destination address
+    if (connect(cloned_sockfd, (struct sockaddr *)storage, sizeof(*storage)) < 0) {
+        tvherror(uc->subsystem, "connect() failed: %s", strerror(errno));
+        return -1;
+    }
+
+    // Get the local endpoint information (source IP address)
+    if (getsockname(cloned_sockfd, (struct sockaddr *)&local_addr, &local_addr_len) == -1) {
+        tvherror(uc->subsystem, "getsockname() failed: %s", strerror(errno));
+        return -1;
+    }
+
+    tvhdebug(uc->subsystem, "Got source IP address: %s", inet_ntoa(local_addr.sin_addr));
+
+    len += strlen(inet_ntoa(local_addr.sin_addr)) - 2;
+    char* data = malloc(len + 1);
+
+    len = snprintf(data, len + 1, buf, inet_ntoa(local_addr.sin_addr));
+
+    tvhdebug(uc->subsystem, "Assembled msg [len: %ld]", len);
+    tvhlog_hexdump(uc->subsystem, data, len);
+
+    // Send data over the established connection
+    char* sdata = data;
+    while (len) {
+        r = write(cloned_sockfd, sdata, len);
+        if (r < 0) {
+            if (ERRNO_AGAIN(errno)) {
+                tvh_safe_usleep(100);
+                continue;
+            }
+            break;
+        }
+        len -= r;
+        sdata += r;
+    }
+
+    free(data);
+    close(cloned_sockfd);
+
+    return len;
+}
+
 int
 udp_write( udp_connection_t *uc, const void *buf, size_t len,
            struct sockaddr_storage *storage )
@@ -521,7 +613,14 @@ udp_write( udp_connection_t *uc, const void *buf, size_t len,
 
 int
 udp_write_queue( udp_connection_t *uc, htsbuf_queue_t *q,
-                 struct sockaddr_storage *storage )
+                 struct sockaddr_storage *storage)
+{
+  return udp_write_queue_fill_source(uc, q, storage, 0);
+}
+
+int
+udp_write_queue_fill_source( udp_connection_t *uc, htsbuf_queue_t *q,
+                 struct sockaddr_storage *storage, int fill_source)
 {
   htsbuf_data_t *hd;
   int l, r = 0;
@@ -531,7 +630,10 @@ udp_write_queue( udp_connection_t *uc, htsbuf_queue_t *q,
     if (!r) {
       l = hd->hd_data_len - hd->hd_data_off;
       p = hd->hd_data + hd->hd_data_off;
-      r = udp_write(uc, p, l, storage);
+      if(fill_source)
+        r = udp_write_fill_source(uc, p, l, storage);
+      else
+        r = udp_write(uc, p, l, storage);
     }
     htsbuf_data_free(q, hd);
   }
index 75328961a6b3edf9083743f5701ed546d961d727..7e2a063861746b68d1aa364289db87797d352782 100644 (file)
--- a/src/udp.h
+++ b/src/udp.h
@@ -66,6 +66,13 @@ udp_write( udp_connection_t *uc, const void *buf, size_t len,
 int
 udp_write_queue( udp_connection_t *uc, htsbuf_queue_t *q,
                  struct sockaddr_storage *storage );
+int
+udp_write_queue_fill_source( udp_connection_t *uc, htsbuf_queue_t *q,
+                 struct sockaddr_storage *storage, int fill_source );
+
+int
+udp_write_fill_source( udp_connection_t *uc, const void *buf, size_t len,
+                       struct sockaddr_storage *storage);
 
 typedef struct udp_multirecv {
   int             um_psize;
index 51dac4291c1b1c34a0d7bebef7e53a92fb047d14..896f0b62598b50d7448a2ef47dc96caf9f7001dd 100644 (file)
@@ -42,6 +42,7 @@ typedef struct upnp_data {
   htsbuf_queue_t queue;
   int delay_ms;
   int from_multicast;
+  int fill_source;
 } upnp_data_t;
 
 TAILQ_HEAD(upnp_data_queue_write, upnp_data);
@@ -75,7 +76,7 @@ void upnp_service_destroy( upnp_service_t *us )
  */
 void
 upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage,
-           int delay_ms, int from_multicast )
+           int delay_ms, int from_multicast, int fill_source )
 {
   upnp_data_t *data;
 
@@ -90,6 +91,7 @@ upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage,
     data->storage = *storage;
   data->delay_ms = delay_ms;
   data->from_multicast = from_multicast;
+  data->fill_source = fill_source;
   tvh_mutex_lock(&upnp_lock);
   TAILQ_INSERT_TAIL(&upnp_data_write, data, data_link);
   tvh_mutex_unlock(&upnp_lock);
@@ -185,8 +187,8 @@ upnp_thread( void *aux )
       if (data == NULL)
         break;
       upnp_dump_data(data);
-      udp_write_queue(data->from_multicast ? multicast : unicast,
-                      &data->queue, &data->storage);
+      udp_write_queue_fill_source(data->from_multicast ? multicast : unicast,
+                      &data->queue, &data->storage, data->fill_source);
       htsbuf_queue_flush(&data->queue);
       free(data);
       delay_ms = 0;
@@ -204,7 +206,7 @@ upnp_thread( void *aux )
       break;
     tvh_safe_usleep((long)data->delay_ms * 1000);
     upnp_dump_data(data);
-    udp_write_queue(unicast, &data->queue, &data->storage);
+    udp_write_queue_fill_source(unicast, &data->queue, &data->storage, data->fill_source);
     htsbuf_queue_flush(&data->queue);
     free(data);
   }
index c2f6726cd83db6f95f2432e71b4f4d2955203cc8..9246ef9e851f280b6b2ef304a8ef4b11496a036e 100644 (file)
@@ -40,7 +40,7 @@ upnp_service_t *upnp_service_create0(upnp_service_t *us);
 void upnp_service_destroy(upnp_service_t *service);
 
 void upnp_send(htsbuf_queue_t *q, struct sockaddr_storage *storage,
-               int delay_ms, int from_multicast);
+               int delay_ms, int from_multicast, int fill_source);
 
 void upnp_server_init(const char *bindaddr);
 void upnp_server_done(void);