From 8783bbb197dbfea2fbafc64e8cfb579f9f90a9e0 Mon Sep 17 00:00:00 2001 From: Flole998 Date: Fri, 9 Feb 2024 22:12:42 +0000 Subject: [PATCH] Remove 8.8.8.8 and instead determine the local IP for each packet --- src/input/mpegts/satip/satip.c | 2 +- src/satip/rtsp.c | 3 +- src/satip/server.c | 61 ++++++++++--------- src/tcp.c | 25 -------- src/tcp.h | 25 ++++++++ src/udp.c | 106 ++++++++++++++++++++++++++++++++- src/udp.h | 7 +++ src/upnp.c | 10 ++-- src/upnp.h | 2 +- 9 files changed, 178 insertions(+), 63 deletions(-) diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index 58e91d30b..e4ecc34c6 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -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, diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index 24efae9d7..239aa4d43 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -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; diff --git a/src/satip/server.c b/src/satip/server.c index 401fd6b63..19f274ce0 100644 --- a/src/satip/server.c +++ b/src/satip/server.c @@ -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); diff --git a/src/tcp.c b/src/tcp.c index 8ff558730..bc11b46da 100644 --- 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 }; diff --git a/src/tcp.h b/src/tcp.h index 5d32b8926..28d59c68e 100644 --- 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); diff --git a/src/udp.c b/src/udp.c index 40cb8308b..32ca3c580 100644 --- 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); } diff --git a/src/udp.h b/src/udp.h index 75328961a..7e2a06386 100644 --- 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; diff --git a/src/upnp.c b/src/upnp.c index 51dac4291..896f0b625 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -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); } diff --git a/src/upnp.h b/src/upnp.h index c2f6726cd..9246ef9e8 100644 --- a/src/upnp.h +++ b/src/upnp.h @@ -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); -- 2.47.2