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