Thanks a lot for the hint Steve. I found that NAK is rejected on receiver side("NAK rejected for unmatched NLA").
It happens in pgm_on_nak(source.c) function:

/* NAK_SRC_NLA contains our sock unicast NLA */
pgm_nla_to_sockaddr (&nak->nak_src_nla_afi, (struct sockaddr*)&nak_src_nla); if (PGM_UNLIKELY(pgm_sockaddr_cmp ((struct sockaddr*)&nak_src_nla, (struct sockaddr*)&sock->send_addr) != 0))
        {
                char saddr[INET6_ADDRSTRLEN];
pgm_sockaddr_ntop ((struct sockaddr*)&nak_src_nla, saddr, sizeof(saddr)); pgm_trace (PGM_LOG_ROLE_NETWORK,_("NAK rejected for unmatched NLA: %s"), saddr);
sock->cumulative_stats[PGM_PC_SOURCE_MALFORMED_NAKS]++;
                return FALSE;
        }

pgm_sockaddr_cmp(sockaddr.c) function compares not only addresses for ipv6 packets, but also sin6_scope_id field. nak_src_nla is filled with pgm_nla_to_sockaddr(sockaddr.c) which does not initialize sin6_scope_id field at all, so compare is always failed. I guess sin6_scope_id should not be compared in this case. I attached the patch that fixes that. It solves problem for me, but I'm not 100% sure that this is correct solution.


On 03.06.2015 02:56, Steven McCoy wrote:
On 2 June 2015 at 19:04, Sergey Zinov <[email protected] <mailto:[email protected]>> wrote:

    it seems that pgm/epgm transport over ipv6 does not work as supposed.
    When a loss(even single) occurs, subscriber pauses for several
    seconds,
    then resumes skipping the lost packets.


This implies recovery is not functioning possibly due to using the wrong interface and scope. Turn on PGM debugging for verbose logging when the socket is created to capture what it is trying to do.

--
Steve-o


_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev


diff -rupN a/openpgm/pgm/sockaddr.c b/openpgm/pgm/sockaddr.c
--- a/openpgm/pgm/sockaddr.c	2011-09-27 19:59:08.000000000 +0200
+++ b/openpgm/pgm/sockaddr.c	2015-06-04 01:53:49.246797685 +0200
@@ -234,9 +234,10 @@ pgm_sockaddr_is_addr_unspecified (
 
 PGM_GNUC_INTERNAL
 int
-pgm_sockaddr_cmp (
+_pgm_sockaddr_cmp (
 	const struct sockaddr* restrict sa1,
-	const struct sockaddr* restrict sa2
+	const struct sockaddr* restrict sa2,
+	const bool check_scope
 	)
 {
 	int retval = 0;
@@ -261,7 +262,7 @@ pgm_sockaddr_cmp (
 			memcpy (&sa1_in6, sa1, sizeof(sa1_in6));
 			memcpy (&sa2_in6, sa2, sizeof(sa2_in6));
 			retval = memcmp (&sa1_in6.sin6_addr, &sa2_in6.sin6_addr, sizeof(struct in6_addr));
-			if (0 == retval && sa1_in6.sin6_scope_id != sa2_in6.sin6_scope_id)
+			if (check_scope && 0 == retval && sa1_in6.sin6_scope_id != sa2_in6.sin6_scope_id)
 				retval = sa1_in6.sin6_scope_id < sa2_in6.sin6_scope_id ? -1 : 1;
 			break;
 		}
@@ -273,6 +274,26 @@ pgm_sockaddr_cmp (
 	return retval;
 }
 
+PGM_GNUC_INTERNAL
+int
+pgm_sockaddr_cmp (
+	const struct sockaddr* restrict sa1,
+	const struct sockaddr* restrict sa2
+	)
+{
+	return _pgm_sockaddr_cmp(sa1, sa2, 1);
+}
+
+PGM_GNUC_INTERNAL
+int
+pgm_sockaddr_no_scope_cmp (
+	const struct sockaddr* restrict sa1,
+	const struct sockaddr* restrict sa2
+	)
+{
+	return _pgm_sockaddr_cmp(sa1, sa2, 0);
+}
+
 /* IP header included with data.
  *
  * If no error occurs, pgm_sockaddr_hdrincl returns zero.  Otherwise, a value
diff -rupN a/openpgm/pgm/source.c b/openpgm/pgm/source.c
--- a/openpgm/pgm/source.c	2011-09-27 19:59:08.000000000 +0200
+++ b/openpgm/pgm/source.c	2015-06-04 01:55:23.778434712 +0200
@@ -316,7 +316,7 @@ pgm_on_nak (
 		
 /* NAK_SRC_NLA contains our sock unicast NLA */
 	pgm_nla_to_sockaddr (&nak->nak_src_nla_afi, (struct sockaddr*)&nak_src_nla);
-	if (PGM_UNLIKELY(pgm_sockaddr_cmp ((struct sockaddr*)&nak_src_nla, (struct sockaddr*)&sock->send_addr) != 0))
+	if (PGM_UNLIKELY(pgm_sockaddr_no_scope_cmp ((struct sockaddr*)&nak_src_nla, (struct sockaddr*)&sock->send_addr) != 0))
 	{
 		char saddr[INET6_ADDRSTRLEN];
 		pgm_sockaddr_ntop ((struct sockaddr*)&nak_src_nla, saddr, sizeof(saddr));
@@ -327,7 +327,7 @@ pgm_on_nak (
 
 /* NAK_GRP_NLA containers our sock multicast group */ 
 	pgm_nla_to_sockaddr ((AF_INET6 == nak_src_nla.ss_family) ? &nak6->nak6_grp_nla_afi : &nak->nak_grp_nla_afi, (struct sockaddr*)&nak_grp_nla);
-	if (PGM_UNLIKELY(pgm_sockaddr_cmp ((struct sockaddr*)&nak_grp_nla, (struct sockaddr*)&sock->send_gsr.gsr_group) != 0))
+	if (PGM_UNLIKELY(pgm_sockaddr_no_scope_cmp ((struct sockaddr*)&nak_grp_nla, (struct sockaddr*)&sock->send_gsr.gsr_group) != 0))
 	{
 		char sgroup[INET6_ADDRSTRLEN];
 		pgm_sockaddr_ntop ((struct sockaddr*)&nak_src_nla, sgroup, sizeof(sgroup));
_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to