From f118dfe468e914a79c8c3a1922336c6245201e8d Mon Sep 17 00:00:00 2001 From: nickkelsey Date: Sun, 4 Dec 2022 13:47:56 -0700 Subject: [PATCH] 20221202 --- hdhomerun_discover.c | 98 ++++++++++++++++++++++++++++------------ hdhomerun_os_posix.c | 8 +++- hdhomerun_os_posix.h | 2 +- hdhomerun_os_windows.c | 4 +- hdhomerun_os_windows.h | 2 +- hdhomerun_sock_netlink.c | 2 +- 6 files changed, 80 insertions(+), 36 deletions(-) diff --git a/hdhomerun_discover.c b/hdhomerun_discover.c index c1220cb..5904e28 100644 --- a/hdhomerun_discover.c +++ b/hdhomerun_discover.c @@ -51,7 +51,7 @@ struct hdhomerun_discover_sock_t { struct sockaddr_storage local_ip; uint32_t ifindex; uint32_t ipv4_subnet_mask; - bool new_flag; + bool active; }; struct hdhomerun_discover_t { @@ -110,7 +110,7 @@ static void hdhomerun_discover_sock_add_ipv6(void *arg, uint32_t ifindex, const while (p) { struct sockaddr_in6 *p_ip = (struct sockaddr_in6 *)&p->local_ip; if ((p->ifindex == ifindex) && (memcmp(p_ip->sin6_addr.s6_addr, local_ip_in6->sin6_addr.s6_addr, 16) == 0)) { - p->new_flag = true; + p->active = true; return; } @@ -144,7 +144,7 @@ static void hdhomerun_discover_sock_add_ipv6(void *arg, uint32_t ifindex, const /* Success. */ memcpy(&dss->local_ip, local_ip_in6, sizeof(struct sockaddr_in6)); dss->ifindex = ifindex; - dss->new_flag = true; + dss->active = true; *pprev = dss; } @@ -169,7 +169,7 @@ static void hdhomerun_discover_sock_add_ipv4(void *arg, uint32_t ifindex, const while (p) { struct sockaddr_in *p_ip = (struct sockaddr_in *)&p->local_ip; if ((p->ifindex == ifindex) && (p_ip->sin_addr.s_addr == local_ip_in->sin_addr.s_addr) && (p->ipv4_subnet_mask == detected_subnet_mask)) { - p->new_flag = true; + p->active = true; return; } @@ -204,7 +204,7 @@ static void hdhomerun_discover_sock_add_ipv4(void *arg, uint32_t ifindex, const memcpy(&dss->local_ip, local_ip_in, sizeof(struct sockaddr_in)); dss->ifindex = ifindex; dss->ipv4_subnet_mask = detected_subnet_mask; - dss->new_flag = true; + dss->active = true; *pprev = dss; } @@ -286,58 +286,54 @@ struct hdhomerun_discover_t *hdhomerun_discover_create(struct hdhomerun_debug_t return ds; } -static void hdhomerun_discover_sock_detect_cleanup(struct hdhomerun_discover_sock_t *default_dss) -{ - struct hdhomerun_discover_sock_t **pprev = &default_dss->next; - struct hdhomerun_discover_sock_t *p = default_dss->next; - while (p) { - if (!p->new_flag) { - *pprev = p->next; - hdhomerun_discover_sock_free(p); - p = *pprev; - continue; - } - - p->new_flag = false; - pprev = &p->next; - p = p->next; - } -} - static void hdhomerun_discover_sock_detect_ipv6(struct hdhomerun_discover_t *ds) { - if (!ds->ipv6_socks) { + struct hdhomerun_discover_sock_t *default_dss = ds->ipv6_socks; + if (!default_dss) { /* Create a routable socket (always first entry). */ struct sockaddr_in6 ipv6_addr; memset(&ipv6_addr, 0, sizeof(ipv6_addr)); ipv6_addr.sin6_family = AF_INET6; hdhomerun_discover_sock_add_ipv6(ds, 0, (const struct sockaddr *)&ipv6_addr, 0); - if (!ds->ipv6_socks) { + default_dss = ds->ipv6_socks; + if (!default_dss) { return; } } + struct hdhomerun_discover_sock_t *p = default_dss->next; + while (p) { + p->active = false; + p = p->next; + } + hdhomerun_local_ip_info2(AF_INET6, hdhomerun_discover_sock_add_ipv6, ds); - hdhomerun_discover_sock_detect_cleanup(ds->ipv6_socks); } static void hdhomerun_discover_sock_detect_ipv4(struct hdhomerun_discover_t *ds) { - if (!ds->ipv4_socks) { + struct hdhomerun_discover_sock_t *default_dss = ds->ipv4_socks; + if (!default_dss) { /* Create a routable socket (always first entry). */ struct sockaddr_in ipv4_addr; memset(&ipv4_addr, 0, sizeof(ipv4_addr)); ipv4_addr.sin_family = AF_INET; hdhomerun_discover_sock_add_ipv4(ds, 0, (const struct sockaddr *)&ipv4_addr, 0); - if (!ds->ipv4_socks) { + default_dss = ds->ipv4_socks; + if (!default_dss) { return; } } + struct hdhomerun_discover_sock_t *p = default_dss->next; + while (p) { + p->active = false; + p = p->next; + } + hdhomerun_local_ip_info2(AF_INET, hdhomerun_discover_sock_add_ipv4, ds); - hdhomerun_discover_sock_detect_cleanup(ds->ipv4_socks); } static void hdhomerun_discover_sock_detect_ipv6_localhost(struct hdhomerun_discover_t *ds) @@ -367,6 +363,7 @@ static void hdhomerun_discover_sock_detect_ipv6_localhost(struct hdhomerun_disco return; } + dss->active = true; ds->ipv6_localhost = dss; } @@ -398,6 +395,7 @@ static void hdhomerun_discover_sock_detect_ipv4_localhost(struct hdhomerun_disco return; } + dss->active = true; ds->ipv4_localhost = dss; } @@ -424,6 +422,11 @@ static void hdhomerun_discover_sock_flush_list(struct hdhomerun_discover_t *ds, struct hdhomerun_discover_sock_t *dss = list; while (dss) { + if (!dss->active) { + dss = dss->next; + continue; + } + while (1) { struct sockaddr_storage remote_addr; size_t length = rx_pkt->limit - rx_pkt->end; @@ -440,6 +443,11 @@ static void hdhomerun_discover_sock_recv_list_append_list(struct hdhomerun_disco { struct hdhomerun_discover_sock_t *dss = list; while (dss) { + if (!dss->active) { + dss = dss->next; + continue; + } + dss->recv_next = *recv_list; *recv_list = dss; dss = dss->next; @@ -475,6 +483,12 @@ static bool hdhomerun_discover_send_request(struct hdhomerun_discover_t *ds, str hdhomerun_pkt_seal_frame(tx_pkt, HDHOMERUN_TYPE_DISCOVER_REQ); + char local_ip_str[64]; + char remote_ip_str[64]; + hdhomerun_sock_sockaddr_to_ip_str(local_ip_str, (const struct sockaddr *)&dss->local_ip, true); + hdhomerun_sock_sockaddr_to_ip_str(remote_ip_str, remote_addr, true); + hdhomerun_debug_printf(ds->dbg, "discover: send to %s via %s\n", remote_ip_str, local_ip_str); + return hdhomerun_sock_sendto_ex(dss->sock, remote_addr, tx_pkt->start, tx_pkt->end - tx_pkt->start, 0); } @@ -496,6 +510,11 @@ static void hdhomerun_discover_send_ipv6_targeted(struct hdhomerun_discover_t *d if (hdhomerun_sock_sockaddr_is_ipv6_linklocal(target_addr) && (target_addr_in.sin6_scope_id == 0)) { struct hdhomerun_discover_sock_t *dss = default_dss->next; while (dss) { + if (!dss->active) { + dss = dss->next; + continue; + } + if (!hdhomerun_sock_sockaddr_is_ipv6_linklocal((const struct sockaddr *)&dss->local_ip)) { dss = dss->next; continue; @@ -537,6 +556,11 @@ static void hdhomerun_discover_send_ipv4_targeted(struct hdhomerun_discover_t *d struct hdhomerun_discover_sock_t *dss = default_dss->next; while (dss) { + if (!dss->active) { + dss = dss->next; + continue; + } + if (dss->ipv4_subnet_mask == 0) { dss = dss->next; continue; @@ -591,6 +615,11 @@ static void hdhomerun_discover_send_ipv6_multicast(struct hdhomerun_discover_t * struct hdhomerun_discover_sock_t *dss = default_dss->next; while (dss) { + if (!dss->active) { + dss = dss->next; + continue; + } + bool linklocal = hdhomerun_sock_sockaddr_is_ipv6_linklocal((const struct sockaddr *)&dss->local_ip); if ((linklocal && !send_linklocal) || (!linklocal && !send_general)) { dss = dss->next; @@ -629,6 +658,11 @@ static void hdhomerun_discover_send_ipv4_broadcast(struct hdhomerun_discover_t * struct hdhomerun_discover_sock_t *dss = default_dss->next; while (dss) { + if (!dss->active) { + dss = dss->next; + continue; + } + #if defined(IP_ONESBCAST) struct sockaddr_in *local_ip_in = (struct sockaddr_in *)&dss->local_ip; uint32_t local_ip_val = ntohl(local_ip_in->sin_addr.s_addr); @@ -1151,6 +1185,12 @@ static bool hdhomerun_discover_recvfrom(struct hdhomerun_discover_t *ds, struct rx_pkt->end += length; activity = true; + char local_ip_str[64]; + char remote_ip_str[64]; + hdhomerun_sock_sockaddr_to_ip_str(local_ip_str, (const struct sockaddr *)&dss->local_ip, true); + hdhomerun_sock_sockaddr_to_ip_str(remote_ip_str, (const struct sockaddr *)&remote_addr, true); + hdhomerun_debug_printf(ds->dbg, "discover: recv from %s via %s\n", remote_ip_str, local_ip_str); + if (!hdhomerun_discover_recvfrom_match_flags((const struct sockaddr *)&remote_addr, flags)) { return activity; } diff --git a/hdhomerun_os_posix.c b/hdhomerun_os_posix.c index 25c7944..3191edf 100644 --- a/hdhomerun_os_posix.c +++ b/hdhomerun_os_posix.c @@ -212,7 +212,7 @@ void thread_cond_wait(thread_cond_t *cond) pthread_mutex_unlock(&cond->lock); } -void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time) +bool thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time) { pthread_mutex_lock(&cond->lock); @@ -224,11 +224,15 @@ void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time) ts.tv_nsec = (long)(tv_nsec % 1000000000); ts.tv_sec += (time_t)(tv_nsec / 1000000000); - pthread_cond_timedwait(&cond->cond, &cond->lock, &ts); + if (pthread_cond_timedwait(&cond->cond, &cond->lock, &ts) != 0) { + pthread_mutex_unlock(&cond->lock); + return false; + } } cond->signaled = false; pthread_mutex_unlock(&cond->lock); + return true; } bool hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap) diff --git a/hdhomerun_os_posix.h b/hdhomerun_os_posix.h index 4ffa66c..8643b64 100644 --- a/hdhomerun_os_posix.h +++ b/hdhomerun_os_posix.h @@ -80,7 +80,7 @@ extern LIBHDHOMERUN_API void thread_cond_init(thread_cond_t *cond); extern LIBHDHOMERUN_API void thread_cond_dispose(thread_cond_t *cond); extern LIBHDHOMERUN_API void thread_cond_signal(thread_cond_t *cond); extern LIBHDHOMERUN_API void thread_cond_wait(thread_cond_t *cond); -extern LIBHDHOMERUN_API void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time); +extern LIBHDHOMERUN_API bool thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time); extern LIBHDHOMERUN_API bool hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap); extern LIBHDHOMERUN_API bool hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...); diff --git a/hdhomerun_os_windows.c b/hdhomerun_os_windows.c index bcea114..42fc741 100644 --- a/hdhomerun_os_windows.c +++ b/hdhomerun_os_windows.c @@ -129,9 +129,9 @@ void thread_cond_wait(thread_cond_t *cond) WaitForSingleObject(*cond, INFINITE); } -void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time) +bool thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time) { - WaitForSingleObject(*cond, (DWORD)max_wait_time); + return (WaitForSingleObject(*cond, (DWORD)max_wait_time) == WAIT_OBJECT_0); } bool hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap) diff --git a/hdhomerun_os_windows.h b/hdhomerun_os_windows.h index 195aa52..fecc60f 100644 --- a/hdhomerun_os_windows.h +++ b/hdhomerun_os_windows.h @@ -104,7 +104,7 @@ extern LIBHDHOMERUN_API void thread_cond_init(thread_cond_t *cond); extern LIBHDHOMERUN_API void thread_cond_dispose(thread_cond_t *cond); extern LIBHDHOMERUN_API void thread_cond_signal(thread_cond_t *cond); extern LIBHDHOMERUN_API void thread_cond_wait(thread_cond_t *cond); -extern LIBHDHOMERUN_API void thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time); +extern LIBHDHOMERUN_API bool thread_cond_wait_with_timeout(thread_cond_t *cond, uint64_t max_wait_time); extern LIBHDHOMERUN_API bool hdhomerun_vsprintf(char *buffer, char *end, const char *fmt, va_list ap); extern LIBHDHOMERUN_API bool hdhomerun_sprintf(char *buffer, char *end, const char *fmt, ...); diff --git a/hdhomerun_sock_netlink.c b/hdhomerun_sock_netlink.c index 87080dd..91bdd3b 100644 --- a/hdhomerun_sock_netlink.c +++ b/hdhomerun_sock_netlink.c @@ -136,7 +136,7 @@ bool hdhomerun_local_ip_info2(int af, hdhomerun_local_ip_info2_callback_t callba return false; } - int nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); + int nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); int af_sock = socket(AF_INET, SOCK_DGRAM, 0); if ((nl_sock == -1) || (af_sock == -1)) { close(af_sock);