mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	module-rtp: for multicast we need to add the TTL
This commit is contained in:
		
							parent
							
								
									c06f936a88
								
							
						
					
					
						commit
						9dd1c78f50
					
				
					 2 changed files with 32 additions and 12 deletions
				
			
		| 
						 | 
					@ -396,7 +396,20 @@ static int parse_address(const char *address, uint16_t port,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int make_multicast_socket(struct sockaddr_storage *src, socklen_t src_len,
 | 
					static bool is_multicast(struct sockaddr *sa, socklen_t salen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (sa->sa_family == AF_INET) {
 | 
				
			||||||
 | 
							static const uint32_t ipv4_mcast_mask = 0xe0000000;
 | 
				
			||||||
 | 
							struct sockaddr_in *sa4 = (struct sockaddr_in*)sa;
 | 
				
			||||||
 | 
							return (ntohl(sa4->sin_addr.s_addr) & ipv4_mcast_mask) == ipv4_mcast_mask;
 | 
				
			||||||
 | 
						} else if (sa->sa_family == AF_INET6) {
 | 
				
			||||||
 | 
							struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)sa;
 | 
				
			||||||
 | 
							return sa6->sin6_addr.s6_addr[0] == 0xff;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int make_socket(struct sockaddr_storage *src, socklen_t src_len,
 | 
				
			||||||
		struct sockaddr_storage *dst, socklen_t dst_len,
 | 
							struct sockaddr_storage *dst, socklen_t dst_len,
 | 
				
			||||||
		bool loop, int ttl)
 | 
							bool loop, int ttl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -417,13 +430,14 @@ static int make_multicast_socket(struct sockaddr_storage *src, socklen_t src_len
 | 
				
			||||||
		pw_log_error("connect() failed: %m");
 | 
							pw_log_error("connect() failed: %m");
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	val = loop;
 | 
						if (is_multicast((struct sockaddr*)dst, dst_len)) {
 | 
				
			||||||
	if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &val, sizeof(val)) < 0)
 | 
							if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &val, sizeof(val)) < 0)
 | 
				
			||||||
		pw_log_warn("setsockopt(IP_MULTICAST_LOOP) failed: %m");
 | 
								pw_log_warn("setsockopt(IP_MULTICAST_LOOP) failed: %m");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val = ttl;
 | 
							val = ttl;
 | 
				
			||||||
	if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, sizeof(val)) < 0)
 | 
							if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, sizeof(val)) < 0)
 | 
				
			||||||
		pw_log_warn("setsockopt(IP_MULTICAST_TTL) failed: %m");
 | 
								pw_log_warn("setsockopt(IP_MULTICAST_TTL) failed: %m");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val = 6;
 | 
						val = 6;
 | 
				
			||||||
	if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val)) < 0)
 | 
						if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val)) < 0)
 | 
				
			||||||
| 
						 | 
					@ -484,7 +498,7 @@ static int setup_stream(struct impl *impl)
 | 
				
			||||||
		return res;
 | 
							return res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((fd = make_multicast_socket(&impl->src_addr, impl->src_len,
 | 
						if ((fd = make_socket(&impl->src_addr, impl->src_len,
 | 
				
			||||||
					&impl->dst_addr, impl->dst_len,
 | 
										&impl->dst_addr, impl->dst_len,
 | 
				
			||||||
					impl->mcast_loop, impl->ttl)) < 0)
 | 
										impl->mcast_loop, impl->ttl)) < 0)
 | 
				
			||||||
		return fd;
 | 
							return fd;
 | 
				
			||||||
| 
						 | 
					@ -508,7 +522,7 @@ static int get_ip(const struct sockaddr_storage *sa, char *ip, size_t len)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static void send_sap(struct impl *impl, bool bye)
 | 
					static void send_sap(struct impl *impl, bool bye)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buffer[2048], src_addr[64], dst_addr[64];
 | 
						char buffer[2048], src_addr[64], dst_addr[64], dst_ttl[8];
 | 
				
			||||||
	const char *user_name, *af;
 | 
						const char *user_name, *af;
 | 
				
			||||||
	struct sockaddr *sa = (struct sockaddr*)&impl->src_addr;
 | 
						struct sockaddr *sa = (struct sockaddr*)&impl->src_addr;
 | 
				
			||||||
	struct sap_header header;
 | 
						struct sap_header header;
 | 
				
			||||||
| 
						 | 
					@ -542,11 +556,15 @@ static void send_sap(struct impl *impl, bool bye)
 | 
				
			||||||
	if ((user_name = pw_get_user_name()) == NULL)
 | 
						if ((user_name = pw_get_user_name()) == NULL)
 | 
				
			||||||
		user_name = "-";
 | 
							user_name = "-";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_zero(dst_ttl);
 | 
				
			||||||
 | 
						if (is_multicast((struct sockaddr*)&impl->dst_addr, impl->dst_len))
 | 
				
			||||||
 | 
							snprintf(dst_ttl, sizeof(dst_ttl), "/%d", impl->ttl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snprintf(buffer, sizeof(buffer),
 | 
						snprintf(buffer, sizeof(buffer),
 | 
				
			||||||
			"v=0\n"
 | 
								"v=0\n"
 | 
				
			||||||
			"o=%s %u 0 IN %s %s\n"
 | 
								"o=%s %u 0 IN %s %s\n"
 | 
				
			||||||
			"s=%s\n"
 | 
								"s=%s\n"
 | 
				
			||||||
			"c=IN %s %s\n"
 | 
								"c=IN %s %s%s\n"
 | 
				
			||||||
			"t=%u 0\n"
 | 
								"t=%u 0\n"
 | 
				
			||||||
			"a=recvonly\n"
 | 
								"a=recvonly\n"
 | 
				
			||||||
			"m=audio %u RTP/AVP %i\n"
 | 
								"m=audio %u RTP/AVP %i\n"
 | 
				
			||||||
| 
						 | 
					@ -554,7 +572,7 @@ static void send_sap(struct impl *impl, bool bye)
 | 
				
			||||||
			"a=type:broadcast\n",
 | 
								"a=type:broadcast\n",
 | 
				
			||||||
			user_name, impl->ntp, af, src_addr,
 | 
								user_name, impl->ntp, af, src_addr,
 | 
				
			||||||
			impl->session_name,
 | 
								impl->session_name,
 | 
				
			||||||
			af, dst_addr,
 | 
								af, dst_addr, dst_ttl,
 | 
				
			||||||
			impl->ntp,
 | 
								impl->ntp,
 | 
				
			||||||
			impl->port, impl->payload,
 | 
								impl->port, impl->payload,
 | 
				
			||||||
			impl->payload, impl->format_info->mime,
 | 
								impl->payload, impl->format_info->mime,
 | 
				
			||||||
| 
						 | 
					@ -585,7 +603,7 @@ static int start_sap_announce(struct impl *impl)
 | 
				
			||||||
	int fd, res;
 | 
						int fd, res;
 | 
				
			||||||
	struct timespec value, interval;
 | 
						struct timespec value, interval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((fd = make_multicast_socket(&impl->src_addr, impl->src_len,
 | 
						if ((fd = make_socket(&impl->src_addr, impl->src_len,
 | 
				
			||||||
					&impl->sap_addr, impl->sap_len,
 | 
										&impl->sap_addr, impl->sap_len,
 | 
				
			||||||
					impl->mcast_loop, impl->ttl)) < 0)
 | 
										impl->mcast_loop, impl->ttl)) < 0)
 | 
				
			||||||
		return fd;
 | 
							return fd;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -559,6 +559,8 @@ static int session_new(struct impl *impl, struct sdp_info *info)
 | 
				
			||||||
			session->target_buffer / (2 * info->stride), info->info.rate);
 | 
								session->target_buffer / (2 * info->stride), info->info.rate);
 | 
				
			||||||
	pw_properties_set(props, "rtp.origin", info->origin);
 | 
						pw_properties_set(props, "rtp.origin", info->origin);
 | 
				
			||||||
	pw_properties_setf(props, "rtp.payload", "%u", info->payload);
 | 
						pw_properties_setf(props, "rtp.payload", "%u", info->payload);
 | 
				
			||||||
 | 
						pw_properties_setf(props, "rtp.fmt", "%s/%u/%u", info->format_info->mime,
 | 
				
			||||||
 | 
								info->info.rate, info->info.channels);
 | 
				
			||||||
	if (info->session[0]) {
 | 
						if (info->session[0]) {
 | 
				
			||||||
		pw_properties_set(props, "rtp.session", info->session);
 | 
							pw_properties_set(props, "rtp.session", info->session);
 | 
				
			||||||
		pw_properties_setf(props, PW_KEY_MEDIA_NAME, "RTP Stream (%s)",
 | 
							pw_properties_setf(props, PW_KEY_MEDIA_NAME, "RTP Stream (%s)",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue