summaryrefslogtreecommitdiffstats
path: root/3rdparty/openpgm-svn-r1135/pgm/receiver.c.c89.patch
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/openpgm-svn-r1135/pgm/receiver.c.c89.patch')
-rw-r--r--3rdparty/openpgm-svn-r1135/pgm/receiver.c.c89.patch887
1 files changed, 887 insertions, 0 deletions
diff --git a/3rdparty/openpgm-svn-r1135/pgm/receiver.c.c89.patch b/3rdparty/openpgm-svn-r1135/pgm/receiver.c.c89.patch
new file mode 100644
index 0000000..a8c3e6d
--- /dev/null
+++ b/3rdparty/openpgm-svn-r1135/pgm/receiver.c.c89.patch
@@ -0,0 +1,887 @@
+--- receiver.c 2010-08-05 11:18:06.000000000 +0800
++++ receiver.c89 2010-08-05 11:39:03.000000000 +0800
+@@ -71,8 +71,10 @@
+ pgm_assert (NULL != window);
+ pgm_assert (NULL != window->ack_backoff_queue.tail);
+
++ {
+ const struct pgm_peer_t* peer = (const struct pgm_peer_t*)window->ack_backoff_queue.tail;
+ return peer->ack_rb_expiry;
++ }
+ }
+
+ static inline
+@@ -84,9 +86,11 @@
+ pgm_assert (NULL != window);
+ pgm_assert (NULL != window->nak_backoff_queue.tail);
+
++ {
+ const struct pgm_sk_buff_t* skb = (const struct pgm_sk_buff_t*)window->nak_backoff_queue.tail;
+ const pgm_rxw_state_t* state = (const pgm_rxw_state_t*)&skb->cb;
+ return state->timer_expiry;
++ }
+ }
+
+ static inline
+@@ -98,9 +102,11 @@
+ pgm_assert (NULL != window);
+ pgm_assert (NULL != window->wait_ncf_queue.tail);
+
++ {
+ const struct pgm_sk_buff_t* skb = (const struct pgm_sk_buff_t*)window->wait_ncf_queue.tail;
+ const pgm_rxw_state_t* state = (const pgm_rxw_state_t*)&skb->cb;
+ return state->timer_expiry;
++ }
+ }
+
+ static inline
+@@ -112,9 +118,11 @@
+ pgm_assert (NULL != window);
+ pgm_assert (NULL != window->wait_data_queue.tail);
+
++ {
+ const struct pgm_sk_buff_t* skb = (const struct pgm_sk_buff_t*)window->wait_data_queue.tail;
+ const pgm_rxw_state_t* state = (const pgm_rxw_state_t*)&skb->cb;
+ return state->timer_expiry;
++ }
+ }
+
+ /* calculate ACK_RB_IVL.
+@@ -127,9 +135,9 @@
+ {
+ /* pre-conditions */
+ pgm_assert (NULL != sock);
+- pgm_assert_cmpuint (sock->ack_bo_ivl, >, 1);
++ pgm_assert_cmpuint ((unsigned int)sock->ack_bo_ivl, >, 1);
+
+- return pgm_rand_int_range (&sock->rand_, 1 /* us */, sock->ack_bo_ivl);
++ return pgm_rand_int_range (&sock->rand_, 1 /* us */, (unsigned int)sock->ack_bo_ivl);
+ }
+
+ /* calculate NAK_RB_IVL as random time interval 1 - NAK_BO_IVL.
+@@ -142,9 +150,9 @@
+ {
+ /* pre-conditions */
+ pgm_assert (NULL != sock);
+- pgm_assert_cmpuint (sock->nak_bo_ivl, >, 1);
++ pgm_assert_cmpuint ((unsigned int)sock->nak_bo_ivl, >, 1);
+
+- return pgm_rand_int_range (&sock->rand_, 1 /* us */, sock->nak_bo_ivl);
++ return pgm_rand_int_range (&sock->rand_, 1 /* us */, (unsigned int)sock->nak_bo_ivl);
+ }
+
+ /* mark sequence as recovery failed.
+@@ -162,11 +170,12 @@
+ pgm_assert (NULL != sock);
+ pgm_assert (NULL != peer);
+ pgm_assert (NULL != skb);
+- pgm_assert_cmpuint (now, >=, skb->tstamp);
++ pgm_assert_cmpuint ((unsigned int)now, >=, (unsigned int)skb->tstamp);
+
+ pgm_trace (PGM_LOG_ROLE_RX_WINDOW, _("Lost data #%u due to cancellation."), skb->sequence);
+
+- const uint32_t fail_time = now - skb->tstamp;
++ {
++ const uint32_t fail_time = (uint32_t)(now - skb->tstamp);
+ if (!peer->max_fail_time)
+ peer->max_fail_time = peer->min_fail_time = fail_time;
+ else if (fail_time > peer->max_fail_time)
+@@ -176,6 +185,7 @@
+
+ pgm_rxw_lost (peer->window, skb->sequence);
+ PGM_HISTOGRAM_TIMES("Rx.FailTime", fail_time);
++ }
+
+ /* mark receiver window for flushing on next recv() */
+ pgm_peer_set_pending (sock, peer);
+@@ -214,6 +224,7 @@
+ pgm_assert (NULL != skb);
+ pgm_assert (NULL != skb->pgm_opt_pgmcc_data);
+
++ {
+ const unsigned acker_afi = ntohs (skb->pgm_opt_pgmcc_data->opt_nla_afi);
+ switch (acker_afi) {
+ case AFI_IP:
+@@ -230,6 +241,7 @@
+ }
+
+ return FALSE;
++ }
+ }
+
+ /* add state for an ACK on a data packet.
+@@ -316,6 +328,7 @@
+ pgm_assert (NULL != skb);
+ pgm_assert (NULL != skb->pgm_data);
+
++ {
+ struct pgm_opt_header* opt_header = (struct pgm_opt_header*)(skb->pgm_data + 1);
+ bool found_opt = FALSE;
+
+@@ -351,6 +364,7 @@
+
+ } while (!(opt_header->opt_type & PGM_OPT_END));
+ return found_opt;
++ }
+ }
+
+ /* a peer in the context of the sock is another party on the network sending PGM
+@@ -381,11 +395,13 @@
+ pgm_assert (dst_addrlen > 0);
+
+ #ifdef PGM_DEBUG
++ {
+ char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN];
+ pgm_sockaddr_ntop (src_addr, saddr, sizeof(saddr));
+ pgm_sockaddr_ntop (dst_addr, daddr, sizeof(daddr));
+ pgm_debug ("pgm_new_peer (sock:%p tsi:%s src-addr:%s src-addrlen:%u dst-addr:%s dst-addrlen:%u)",
+ (void*)sock, pgm_tsi_print (tsi), saddr, (unsigned)src_addrlen, daddr, (unsigned)dst_addrlen);
++ }
+ #endif
+
+ peer = pgm_new0 (pgm_peer_t, 1);
+@@ -409,10 +425,12 @@
+
+ /* add peer to hash table and linked list */
+ pgm_rwlock_writer_lock (&sock->peers_lock);
++ {
+ pgm_peer_t* entry = _pgm_peer_ref (peer);
+ pgm_hashtable_insert (sock->peers_hashtable, &peer->tsi, entry);
+ peer->peers_link.data = peer;
+ sock->peers_list = pgm_list_prepend_link (sock->peers_list, &peer->peers_link);
++ }
+ pgm_rwlock_writer_unlock (&sock->peers_lock);
+
+ pgm_timer_lock (sock);
+@@ -455,6 +473,7 @@
+ pgm_peer_t* peer = sock->peers_pending->data;
+ if (peer->last_commit && peer->last_commit < sock->last_commit)
+ pgm_rxw_remove_commit (peer->window);
++ {
+ const ssize_t peer_bytes = pgm_rxw_readv (peer->window, pmsg, msg_end - *pmsg + 1);
+
+ if (peer->last_cumulative_losses != ((pgm_rxw_t*)peer->window)->cumulative_losses)
+@@ -481,6 +500,7 @@
+ }
+ /* clear this reference and move to next */
+ sock->peers_pending = pgm_slist_remove_first (sock->peers_pending);
++ }
+ }
+
+ return retval;
+@@ -537,6 +557,7 @@
+ pgm_assert (NULL != source);
+ pgm_assert (NULL != msgv);
+
++ {
+ struct pgm_sk_buff_t* error_skb = pgm_alloc_skb (0);
+ error_skb->sock = sock;
+ error_skb->tstamp = pgm_time_update_now ();
+@@ -544,6 +565,7 @@
+ error_skb->sequence = source->lost_count;
+ msgv->msgv_skb[0] = error_skb;
+ msgv->msgv_len = 1;
++ }
+ }
+
+ /* SPM indicate start of a session, continued presence of a session, or flushing final packets
+@@ -573,6 +595,7 @@
+ return FALSE;
+ }
+
++ {
+ const struct pgm_spm* spm = (struct pgm_spm*) skb->data;
+ const struct pgm_spm6* spm6 = (struct pgm_spm6*)skb->data;
+ const uint32_t spm_sqn = ntohl (spm->spm_sqn);
+@@ -587,6 +610,7 @@
+ source->spm_sqn = spm_sqn;
+
+ /* update receive window */
++ {
+ const pgm_time_t nak_rb_expiry = skb->tstamp + nak_rb_ivl (sock);
+ const unsigned naks = pgm_rxw_update (source->window,
+ ntohl (spm->spm_lead),
+@@ -601,6 +625,7 @@
+ }
+
+ /* mark receiver window for flushing on next recv() */
++ {
+ const pgm_rxw_t* window = source->window;
+ if (window->cumulative_losses != source->last_cumulative_losses &&
+ !source->pending_link.data)
+@@ -610,6 +635,8 @@
+ source->last_cumulative_losses = window->cumulative_losses;
+ pgm_peer_set_pending (sock, source);
+ }
++ }
++ }
+ }
+ else
+ { /* does not advance SPM sequence number */
+@@ -637,6 +664,7 @@
+ return FALSE;
+ }
+ /* TODO: check for > 16 options & past packet end */
++ {
+ const struct pgm_opt_header* opt_header = (const struct pgm_opt_header*)opt_len;
+ do {
+ opt_header = (const struct pgm_opt_header*)((const char*)opt_header + opt_header->opt_length);
+@@ -650,6 +678,7 @@
+ return FALSE;
+ }
+
++ {
+ const uint32_t parity_prm_tgs = ntohl (opt_parity_prm->parity_prm_tgs);
+ if (PGM_UNLIKELY(parity_prm_tgs < 2 || parity_prm_tgs > 128))
+ {
+@@ -664,8 +693,10 @@
+ source->is_fec_enabled = 1;
+ pgm_rxw_update_fec (source->window, parity_prm_tgs);
+ }
++ }
+ }
+ } while (!(opt_header->opt_type & PGM_OPT_END));
++ }
+ }
+
+ /* either way bump expiration timer */
+@@ -676,6 +707,7 @@
+ source->spmr_tstamp = 0;
+ }
+ return TRUE;
++ }
+ }
+
+ /* Multicast peer-to-peer NAK handling, pretty much the same as a NCF but different direction
+@@ -705,6 +737,7 @@
+ return FALSE;
+ }
+
++ {
+ const struct pgm_nak* nak = (struct pgm_nak*) skb->data;
+ const struct pgm_nak6* nak6 = (struct pgm_nak6*)skb->data;
+
+@@ -718,10 +751,14 @@
+ }
+
+ /* NAK_GRP_NLA contains one of our sock receive multicast groups: the sources send multicast group */
++ {
+ struct sockaddr_storage nak_grp_nla;
+ 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);
++ {
+ bool found = FALSE;
+- for (unsigned i = 0; i < sock->recv_gsr_len; i++)
++ {
++ unsigned i;
++ for (i = 0; i < sock->recv_gsr_len; i++)
+ {
+ if (pgm_sockaddr_cmp ((struct sockaddr*)&nak_grp_nla, (struct sockaddr*)&sock->recv_gsr[i].gsr_group) == 0)
+ {
+@@ -729,6 +766,7 @@
+ break;
+ }
+ }
++ }
+
+ if (PGM_UNLIKELY(!found)) {
+ pgm_trace (PGM_LOG_ROLE_NETWORK,_("Discarded multicast NAK on multicast group mismatch."));
+@@ -736,6 +774,7 @@
+ }
+
+ /* handle as NCF */
++ {
+ int status = pgm_rxw_confirm (peer->window,
+ ntohl (nak->nak_sqn),
+ skb->tstamp,
+@@ -745,6 +784,7 @@
+ peer->cumulative_stats[PGM_PC_RECEIVER_SELECTIVE_NAKS_SUPPRESSED]++;
+
+ /* check NAK list */
++ {
+ const uint32_t* nak_list = NULL;
+ unsigned nak_list_len = 0;
+ if (skb->pgm_header->pgm_options & PGM_OPT_PRESENT)
+@@ -765,6 +805,7 @@
+ return FALSE;
+ }
+ /* TODO: check for > 16 options & past packet end */
++ {
+ const struct pgm_opt_header* opt_header = (const struct pgm_opt_header*)opt_len;
+ do {
+ opt_header = (const struct pgm_opt_header*)((const char*)opt_header + opt_header->opt_length);
+@@ -775,6 +816,7 @@
+ break;
+ }
+ } while (!(opt_header->opt_type & PGM_OPT_END));
++ }
+ }
+
+ while (nak_list_len) {
+@@ -790,6 +832,7 @@
+ }
+
+ /* mark receiver window for flushing on next recv() */
++ {
+ const pgm_rxw_t* window = peer->window;
+ if (window->cumulative_losses != peer->last_cumulative_losses &&
+ !peer->pending_link.data)
+@@ -800,6 +843,12 @@
+ pgm_peer_set_pending (sock, peer);
+ }
+ return TRUE;
++ }
++ }
++ }
++ }
++ }
++ }
+ }
+
+ /* NCF confirming receipt of a NAK from this sock or another on the LAN segment.
+@@ -831,6 +880,7 @@
+ return FALSE;
+ }
+
++ {
+ const struct pgm_nak* ncf = (struct pgm_nak*) skb->data;
+ const struct pgm_nak6* ncf6 = (struct pgm_nak6*)skb->data;
+
+@@ -847,6 +897,7 @@
+ #endif
+
+ /* NCF_GRP_NLA contains our sock multicast group */
++ {
+ struct sockaddr_storage ncf_grp_nla;
+ pgm_nla_to_sockaddr ((AF_INET6 == ncf_src_nla.ss_family) ? &ncf6->nak6_grp_nla_afi : &ncf->nak_grp_nla_afi, (struct sockaddr*)&ncf_grp_nla);
+ if (PGM_UNLIKELY(pgm_sockaddr_cmp ((struct sockaddr*)&ncf_grp_nla, (struct sockaddr*)&sock->send_gsr.gsr_group) != 0))
+@@ -855,6 +906,7 @@
+ return FALSE;
+ }
+
++ {
+ const pgm_time_t ncf_rdata_ivl = skb->tstamp + sock->nak_rdata_ivl;
+ const pgm_time_t ncf_rb_ivl = skb->tstamp + nak_rb_ivl(sock);
+ int status = pgm_rxw_confirm (source->window,
+@@ -874,6 +926,7 @@
+ }
+
+ /* check NCF list */
++ {
+ const uint32_t* ncf_list = NULL;
+ unsigned ncf_list_len = 0;
+ if (skb->pgm_header->pgm_options & PGM_OPT_PRESENT)
+@@ -894,6 +947,7 @@
+ return FALSE;
+ }
+ /* TODO: check for > 16 options & past packet end */
++ {
+ const struct pgm_opt_header* opt_header = (const struct pgm_opt_header*)opt_len;
+ do {
+ opt_header = (const struct pgm_opt_header*)((const char*)opt_header + opt_header->opt_length);
+@@ -904,6 +958,7 @@
+ break;
+ }
+ } while (!(opt_header->opt_type & PGM_OPT_END));
++ }
+ }
+
+ pgm_debug ("NCF contains 1+%d sequence numbers.", ncf_list_len);
+@@ -921,6 +976,7 @@
+ }
+
+ /* mark receiver window for flushing on next recv() */
++ {
+ const pgm_rxw_t* window = source->window;
+ if (window->cumulative_losses != source->last_cumulative_losses &&
+ !source->pending_link.data)
+@@ -931,6 +987,11 @@
+ pgm_peer_set_pending (sock, source);
+ }
+ return TRUE;
++ }
++ }
++ }
++ }
++ }
+ }
+
+ /* send SPM-request to a new peer, this packet type has no contents
+@@ -953,8 +1014,9 @@
+ pgm_debug ("send_spmr (sock:%p source:%p)",
+ (const void*)sock, (const void*)source);
+
++ {
+ const size_t tpdu_length = sizeof(struct pgm_header);
+- char buf[ tpdu_length ];
++ char* buf = pgm_newa (char, tpdu_length);
+ struct pgm_header* header = (struct pgm_header*)buf;
+ memcpy (header->pgm_gsi, &source->tsi.gsi, sizeof(pgm_gsi_t));
+ /* dport & sport reversed communicating upstream */
+@@ -968,6 +1030,7 @@
+
+ /* send multicast SPMR TTL 1 */
+ pgm_sockaddr_multicast_hops (sock->send_sock, sock->send_gsr.gsr_group.ss_family, 1);
++ {
+ ssize_t sent = pgm_sendto (sock,
+ FALSE, /* not rate limited */
+ FALSE, /* regular socket */
+@@ -992,6 +1055,8 @@
+
+ sock->cumulative_stats[PGM_PC_SOURCE_BYTES_SENT] += tpdu_length * 2;
+ return TRUE;
++ }
++ }
+ }
+
+ /* send selective NAK for one sequence number.
+@@ -1014,10 +1079,12 @@
+ pgm_debug ("send_nak (sock:%p peer:%p sequence:%" PRIu32 ")",
+ (void*)sock, (void*)source, sequence);
+
++ {
+ size_t tpdu_length = sizeof(struct pgm_header) + sizeof(struct pgm_nak);
+ if (AF_INET6 == source->nla.ss_family)
+ tpdu_length += sizeof(struct pgm_nak6) - sizeof(struct pgm_nak);
+- char buf[ tpdu_length ];
++ {
++ char* buf = pgm_newa (char, tpdu_length);
+ struct pgm_header* header = (struct pgm_header*)buf;
+ struct pgm_nak* nak = (struct pgm_nak* )(header + 1);
+ struct pgm_nak6* nak6 = (struct pgm_nak6*)(header + 1);
+@@ -1045,6 +1112,7 @@
+ header->pgm_checksum = 0;
+ header->pgm_checksum = pgm_csum_fold (pgm_csum_partial (buf, tpdu_length, 0));
+
++ {
+ const ssize_t sent = pgm_sendto (sock,
+ FALSE, /* not rate limited */
+ TRUE, /* with router alert */
+@@ -1058,6 +1126,9 @@
+ source->cumulative_stats[PGM_PC_RECEIVER_SELECTIVE_NAK_PACKETS_SENT]++;
+ source->cumulative_stats[PGM_PC_RECEIVER_SELECTIVE_NAKS_SENT]++;
+ return TRUE;
++ }
++ }
++ }
+ }
+
+ /* Send a parity NAK requesting on-demand parity packet generation.
+@@ -1082,10 +1153,12 @@
+ pgm_debug ("send_parity_nak (sock:%p source:%p nak-tg-sqn:%" PRIu32 " nak-pkt-cnt:%" PRIu32 ")",
+ (void*)sock, (void*)source, nak_tg_sqn, nak_pkt_cnt);
+
++ {
+ size_t tpdu_length = sizeof(struct pgm_header) + sizeof(struct pgm_nak);
+ if (AF_INET6 == source->nla.ss_family)
+ tpdu_length += sizeof(struct pgm_nak6) - sizeof(struct pgm_nak);
+- char buf[ tpdu_length ];
++ {
++ char* buf = pgm_newa (char, tpdu_length);
+ struct pgm_header* header = (struct pgm_header*)buf;
+ struct pgm_nak* nak = (struct pgm_nak* )(header + 1);
+ struct pgm_nak6* nak6 = (struct pgm_nak6*)(header + 1);
+@@ -1112,6 +1185,7 @@
+ header->pgm_checksum = 0;
+ header->pgm_checksum = pgm_csum_fold (pgm_csum_partial (buf, tpdu_length, 0));
+
++ {
+ const ssize_t sent = pgm_sendto (sock,
+ FALSE, /* not rate limited */
+ TRUE, /* with router alert */
+@@ -1125,6 +1199,9 @@
+ source->cumulative_stats[PGM_PC_RECEIVER_PARITY_NAK_PACKETS_SENT]++;
+ source->cumulative_stats[PGM_PC_RECEIVER_PARITY_NAKS_SENT]++;
+ return TRUE;
++ }
++ }
++ }
+ }
+
+ /* A NAK packet with a OPT_NAK_LIST option extension
+@@ -1148,17 +1225,23 @@
+ pgm_assert_cmpuint (sqn_list->len, <=, 63);
+
+ #ifdef RECEIVER_DEBUG
++ {
+ char list[1024];
+ sprintf (list, "%" PRIu32, sqn_list->sqn[0]);
+- for (unsigned i = 1; i < sqn_list->len; i++) {
++ {
++ unsigned i;
++ for (i = 1; i < sqn_list->len; i++) {
+ char sequence[2 + strlen("4294967295")];
+ sprintf (sequence, " %" PRIu32, sqn_list->sqn[i]);
+ strcat (list, sequence);
+ }
++ }
+ pgm_debug("send_nak_list (sock:%p source:%p sqn-list:[%s])",
+ (const void*)sock, (const void*)source, list);
++ }
+ #endif
+
++ {
+ size_t tpdu_length = sizeof(struct pgm_header) +
+ sizeof(struct pgm_nak) +
+ sizeof(struct pgm_opt_length) + /* includes header */
+@@ -1167,9 +1250,11 @@
+ ( (sqn_list->len-1) * sizeof(uint32_t) );
+ if (AF_INET6 == source->nla.ss_family)
+ tpdu_length += sizeof(struct pgm_nak6) - sizeof(struct pgm_nak);
+- char buf[ tpdu_length ];
++ {
++ char* buf = pgm_newa (char, tpdu_length);
+ if (PGM_UNLIKELY(pgm_mem_gc_friendly))
+ memset (buf, 0, tpdu_length);
++ {
+ struct pgm_header* header = (struct pgm_header*)buf;
+ struct pgm_nak* nak = (struct pgm_nak* )(header + 1);
+ struct pgm_nak6* nak6 = (struct pgm_nak6*)(header + 1);
+@@ -1193,6 +1278,7 @@
+ (AF_INET6 == source->nla.ss_family) ? (char*)&nak6->nak6_grp_nla_afi : (char*)&nak->nak_grp_nla_afi);
+
+ /* OPT_NAK_LIST */
++ {
+ struct pgm_opt_length* opt_len = (AF_INET6 == source->nla.ss_family) ? (struct pgm_opt_length*)(nak6 + 1) : (struct pgm_opt_length*)(nak + 1);
+ opt_len->opt_type = PGM_OPT_LENGTH;
+ opt_len->opt_length = sizeof(struct pgm_opt_length);
+@@ -1200,19 +1286,25 @@
+ sizeof(struct pgm_opt_header) +
+ sizeof(struct pgm_opt_nak_list) +
+ ( (sqn_list->len-1) * sizeof(uint32_t) ) );
++ {
+ struct pgm_opt_header* opt_header = (struct pgm_opt_header*)(opt_len + 1);
+ opt_header->opt_type = PGM_OPT_NAK_LIST | PGM_OPT_END;
+ opt_header->opt_length = sizeof(struct pgm_opt_header) + sizeof(struct pgm_opt_nak_list)
+ + ( (sqn_list->len-1) * sizeof(uint32_t) );
++ {
+ struct pgm_opt_nak_list* opt_nak_list = (struct pgm_opt_nak_list*)(opt_header + 1);
+ opt_nak_list->opt_reserved = 0;
+
+- for (unsigned i = 1; i < sqn_list->len; i++)
++ {
++ unsigned i;
++ for (i = 1; i < sqn_list->len; i++)
+ opt_nak_list->opt_sqn[i-1] = htonl (sqn_list->sqn[i]);
++ }
+
+ header->pgm_checksum = 0;
+ header->pgm_checksum = pgm_csum_fold (pgm_csum_partial (buf, tpdu_length, 0));
+
++ {
+ const ssize_t sent = pgm_sendto (sock,
+ FALSE, /* not rate limited */
+ FALSE, /* regular socket */
+@@ -1226,6 +1318,13 @@
+ source->cumulative_stats[PGM_PC_RECEIVER_SELECTIVE_NAK_PACKETS_SENT]++;
+ source->cumulative_stats[PGM_PC_RECEIVER_SELECTIVE_NAKS_SENT] += 1 + sqn_list->len;
+ return TRUE;
++ }
++ }
++ }
++ }
++ }
++ }
++ }
+ }
+
+ /* send ACK upstream to source
+@@ -1248,6 +1347,7 @@
+ pgm_debug ("send_ack (sock:%p source:%p now:%" PGM_TIME_FORMAT ")",
+ (const void*)sock, (const void*)source, now);
+
++ {
+ size_t tpdu_length = sizeof(struct pgm_header) +
+ sizeof(struct pgm_ack) +
+ sizeof(struct pgm_opt_length) + /* includes header */
+@@ -1255,9 +1355,11 @@
+ sizeof(struct pgm_opt_pgmcc_feedback);
+ if (AF_INET6 == sock->send_addr.ss_family)
+ tpdu_length += sizeof(struct pgm_opt6_pgmcc_feedback) - sizeof(struct pgm_opt_pgmcc_feedback);
+- char buf[ tpdu_length ];
++ {
++ char* buf = pgm_newa (char, tpdu_length);
+ if (PGM_UNLIKELY(pgm_mem_gc_friendly))
+ memset (buf, 0, tpdu_length);
++ {
+ struct pgm_header* header = (struct pgm_header*)buf;
+ struct pgm_ack* ack = (struct pgm_ack*)(header + 1);
+ memcpy (header->pgm_gsi, &source->tsi.gsi, sizeof(pgm_gsi_t));
+@@ -1274,6 +1376,7 @@
+ ack->ack_bitmap = htonl (source->window->bitmap);
+
+ /* OPT_PGMCC_FEEDBACK */
++ {
+ struct pgm_opt_length* opt_len = (struct pgm_opt_length*)(ack + 1);
+ opt_len->opt_type = PGM_OPT_LENGTH;
+ opt_len->opt_length = sizeof(struct pgm_opt_length);
+@@ -1282,16 +1385,19 @@
+ (AF_INET6 == sock->send_addr.ss_family) ?
+ sizeof(struct pgm_opt6_pgmcc_feedback) :
+ sizeof(struct pgm_opt_pgmcc_feedback) );
++ {
+ struct pgm_opt_header* opt_header = (struct pgm_opt_header*)(opt_len + 1);
+ opt_header->opt_type = PGM_OPT_PGMCC_FEEDBACK | PGM_OPT_END;
+ opt_header->opt_length = sizeof(struct pgm_opt_header) +
+ ( (AF_INET6 == sock->send_addr.ss_family) ?
+ sizeof(struct pgm_opt6_pgmcc_feedback) :
+ sizeof(struct pgm_opt_pgmcc_feedback) );
++ {
+ struct pgm_opt_pgmcc_feedback* opt_pgmcc_feedback = (struct pgm_opt_pgmcc_feedback*)(opt_header + 1);
+ opt_pgmcc_feedback->opt_reserved = 0;
+
+- const uint32_t t = source->ack_last_tstamp + pgm_to_msecs( now - source->last_data_tstamp );
++ {
++ const uint32_t t = (uint32_t)(source->ack_last_tstamp + pgm_to_msecs( now - source->last_data_tstamp ));
+ opt_pgmcc_feedback->opt_tstamp = htonl (t);
+ pgm_sockaddr_to_nla ((struct sockaddr*)&sock->send_addr, (char*)&opt_pgmcc_feedback->opt_nla_afi);
+ opt_pgmcc_feedback->opt_loss_rate = htons ((uint16_t)source->window->data_loss);
+@@ -1299,6 +1405,7 @@
+ header->pgm_checksum = 0;
+ header->pgm_checksum = pgm_csum_fold (pgm_csum_partial (buf, tpdu_length, 0));
+
++ {
+ const ssize_t sent = pgm_sendto (sock,
+ FALSE, /* not rate limited */
+ FALSE, /* regular socket */
+@@ -1311,6 +1418,14 @@
+
+ source->cumulative_stats[PGM_PC_RECEIVER_ACKS_SENT]++;
+ return TRUE;
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
+ }
+
+ /* check all receiver windows for ACKer elections, on expiration send an ACK.
+@@ -1331,6 +1446,7 @@
+ pgm_debug ("ack_rb_state (peer:%p now:%" PGM_TIME_FORMAT ")",
+ (const void*)peer, now);
+
++ {
+ pgm_rxw_t* window = peer->window;
+ pgm_sock_t* sock = peer->sock;
+ pgm_list_t* list;
+@@ -1345,6 +1461,7 @@
+ }
+
+ /* have not learned this peers NLA */
++ {
+ const bool is_valid_nla = (0 != peer->nla.ss_family);
+
+ while (list)
+@@ -1397,6 +1514,8 @@
+ pgm_trace (PGM_LOG_ROLE_RX_WINDOW,_("ACK backoff queue empty."));
+ }
+ return TRUE;
++ }
++ }
+ }
+
+ /* check all receiver windows for packets in BACK-OFF_STATE, on expiration send a NAK.
+@@ -1420,10 +1539,11 @@
+ pgm_debug ("nak_rb_state (peer:%p now:%" PGM_TIME_FORMAT ")",
+ (const void*)peer, now);
+
++ {
+ pgm_rxw_t* window = peer->window;
+ pgm_sock_t* sock = peer->sock;
+ pgm_list_t* list;
+- struct pgm_sqn_list_t nak_list = { .len = 0 };
++ struct pgm_sqn_list_t nak_list = { 0 };
+
+ /* send all NAKs first, lack of data is blocking contiguous processing and its
+ * better to get the notification out a.s.a.p. even though it might be waiting
+@@ -1441,6 +1561,7 @@
+ pgm_assert (window->nak_backoff_queue.head != NULL);
+ }
+
++ {
+ unsigned dropped_invalid = 0;
+
+ /* have not learned this peers NLA */
+@@ -1480,6 +1601,7 @@
+ }
+
+ /* TODO: parity nak lists */
++ {
+ const uint32_t tg_sqn = skb->sequence & tg_sqn_mask;
+ if ( ( nak_pkt_cnt && tg_sqn == nak_tg_sqn ) ||
+ ( !nak_pkt_cnt && tg_sqn != current_tg_sqn ) )
+@@ -1508,6 +1630,7 @@
+ { /* different transmission group */
+ break;
+ }
++ }
+ }
+ else
+ { /* packet expires some time later */
+@@ -1627,6 +1750,8 @@
+ pgm_trace (PGM_LOG_ROLE_RX_WINDOW,_("NAK backoff queue empty."));
+ }
+ return TRUE;
++ }
++ }
+ }
+
+ /* check this peer for NAK state timers, uses the tail of each queue for the nearest
+@@ -1650,6 +1775,7 @@
+ if (!sock->peers_list)
+ return TRUE;
+
++ {
+ pgm_list_t* list = sock->peers_list;
+ do {
+ pgm_list_t* next = list->next;
+@@ -1733,6 +1859,7 @@
+ sock->is_pending_read = TRUE;
+ }
+ return TRUE;
++ }
+ }
+
+ /* find the next state expiration time among the socks peers.
+@@ -1756,6 +1883,7 @@
+ if (!sock->peers_list)
+ return expiration;
+
++ {
+ pgm_list_t* list = sock->peers_list;
+ do {
+ pgm_list_t* next = list->next;
+@@ -1796,6 +1924,7 @@
+ } while (list);
+
+ return expiration;
++ }
+ }
+
+ /* check WAIT_NCF_STATE, on expiration move back to BACK-OFF_STATE, on exceeding NAK_NCF_RETRIES
+@@ -1814,6 +1943,7 @@
+ pgm_debug ("nak_rpt_state (peer:%p now:%" PGM_TIME_FORMAT ")",
+ (void*)peer, now);
+
++ {
+ pgm_rxw_t* window = peer->window;
+ pgm_sock_t* sock = peer->sock;
+ pgm_list_t* list = window->wait_ncf_queue.tail;
+@@ -1923,6 +2053,7 @@
+ {
+ pgm_trace (PGM_LOG_ROLE_RX_WINDOW,_("Wait ncf queue empty."));
+ }
++ }
+ }
+
+ /* check WAIT_DATA_STATE, on expiration move back to BACK-OFF_STATE, on exceeding NAK_DATA_RETRIES
+@@ -1941,6 +2072,7 @@
+ pgm_debug ("nak_rdata_state (peer:%p now:%" PGM_TIME_FORMAT ")",
+ (const void*)peer, now);
+
++ {
+ pgm_rxw_t* window = peer->window;
+ pgm_sock_t* sock = peer->sock;
+ pgm_list_t* list = window->wait_data_queue.tail;
+@@ -1956,6 +2088,7 @@
+ pgm_list_t* next_list_el = list->prev;
+ struct pgm_sk_buff_t* rdata_skb = (struct pgm_sk_buff_t*)list;
+ pgm_assert (NULL != rdata_skb);
++ {
+ pgm_rxw_state_t* rdata_state = (pgm_rxw_state_t*)&rdata_skb->cb;
+
+ /* check this packet for state expiration */
+@@ -1991,8 +2124,8 @@
+ break;
+ }
+
+-
+ list = next_list_el;
++ }
+ }
+
+ if (window->wait_data_queue.length == 0)
+@@ -2029,6 +2162,7 @@
+ } else {
+ pgm_trace (PGM_LOG_ROLE_RX_WINDOW,_("Wait data queue empty."));
+ }
++ }
+ }
+
+ /* ODATA or RDATA packet with any of the following options:
+@@ -2055,6 +2189,7 @@
+ pgm_debug ("pgm_on_data (sock:%p source:%p skb:%p)",
+ (void*)sock, (void*)source, (void*)skb);
+
++ {
+ unsigned msg_count = 0;
+ const pgm_time_t nak_rb_expiry = skb->tstamp + nak_rb_ivl (sock);
+ pgm_time_t ack_rb_expiry = 0;
+@@ -2062,6 +2197,7 @@
+
+ skb->pgm_data = skb->data;
+
++ {
+ const unsigned opt_total_length = (skb->pgm_header->pgm_options & PGM_OPT_PRESENT) ? ntohs(*(uint16_t*)( (char*)( skb->pgm_data + 1 ) + sizeof(uint16_t))) : 0;
+
+ /* advance data pointer to payload */
+@@ -2076,6 +2212,7 @@
+ ack_rb_expiry = skb->tstamp + ack_rb_ivl (sock);
+ }
+
++ {
+ const int add_status = pgm_rxw_add (source->window, skb, skb->tstamp, nak_rb_expiry);
+
+ /* skb reference is now invalid */
+@@ -2155,6 +2292,9 @@
+ pgm_timer_unlock (sock);
+ }
+ return TRUE;
++ }
++ }
++ }
+ }
+
+ /* POLLs are generated by PGM Parents (Sources or Network Elements).
+@@ -2182,10 +2322,12 @@
+ return FALSE;
+ }
+
++ {
+ struct pgm_poll* poll4 = (struct pgm_poll*) skb->data;
+ struct pgm_poll6* poll6 = (struct pgm_poll6*)skb->data;
+ uint32_t poll_rand;
+ memcpy (&poll_rand, (AFI_IP6 == ntohs (poll4->poll_nla_afi)) ? poll6->poll6_rand : poll4->poll_rand, sizeof(poll_rand));
++ {
+ const uint32_t poll_mask = (AFI_IP6 == ntohs (poll4->poll_nla_afi)) ? ntohl (poll6->poll6_mask) : ntohl (poll4->poll_mask);
+
+ /* Check for probability match */
+@@ -2199,6 +2341,7 @@
+ /* scoped per path nla
+ * TODO: manage list of pollers per peer
+ */
++ {
+ const uint32_t poll_sqn = ntohl (poll4->poll_sqn);
+ const uint16_t poll_round = ntohs (poll4->poll_round);
+
+@@ -2213,6 +2356,7 @@
+ source->last_poll_sqn = poll_sqn;
+ source->last_poll_round = poll_round;
+
++ {
+ const uint16_t poll_s_type = ntohs (poll4->poll_s_type);
+
+ /* Check poll type */
+@@ -2229,6 +2373,10 @@
+ }
+
+ return FALSE;
++ }
++ }
++ }
++ }
+ }
+
+ /* Used to count PGM children */