summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar David Benjamin <davidben@mit.edu>2013-07-14 14:56:10 -0400
committerGravatar Karl Ramm <kcr@1ts.org>2013-08-08 00:24:58 -0400
commit32da3192e9169118365a236ac8ccd1bf982df020 (patch)
treee6872abc2ca92f61f00cf080c1bdf2e8122983ed
parentb9ec2cdc23b77fd86b69ba884c5513f3f71cf025 (diff)
Defensively avoid waiting on non-initial SERVACKs
Although the previous commit should make it very unlikely we screw up the subscription sharding, be defensive about waiting for SERVACKs. ZSubscribeTo does mess up, Z_SendFragmentedNotice will shard with a z_multiuid. In that case, although the second packet will get a SERVACK, Z_ReadWait kindly drops it on the floor. The ZIfNotice will then just hang. Tested by bumping zwgc's BATCH_SIZE up to 200, reverting the previous commit, and strace.
-rw-r--r--lib/ZSubs.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/lib/ZSubs.c b/lib/ZSubs.c
index e0d39ee..7c7949b 100644
--- a/lib/ZSubs.c
+++ b/lib/ZSubs.c
@@ -188,6 +188,11 @@ Z_SendAndWaitForServer(ZNotice_t *notice,
retval = ZSendPacket(buf, len, waitforack);
if (retval != ZERR_NONE)
return (retval);
+ /* Z_ReadWait drops non-initial SERVACKs and SERVNAKs on the floor. We
+ should never see a non-initial one here, but be defensive about bugs in the
+ sharding code above. */
+ if (!ZCompareUID(&notice->z_multiuid, &notice->z_uid))
+ return (retval);
if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0,
ZCompareUIDPred, (char *)&notice->z_uid)) !=
ZERR_NONE)