Permalink
Browse files

Decode TAP mutation flags as host byte order.

In trying to decode the item flags from a tap mutation, it was found
that the flags are stored in the server in network byte order, but
when sent over tap it goes through htonl() conversion, making it a
double conversion.

Future versions of the server now allow for the client to specify
it would like the flags sent correctly, via a TAP flag, and the
server will set a flag to say they're being sent correctly.  With
this change, we now request things to be correct and if we don't
receive a flag saying it's correct, we swap the bytes (assuming we
are talking to a 'broken' server).

In developing this change, a test was also developed but to
complete the test correctly, some other issues had to be fixed.
Thus the test isn't in this commit, but rather in it's own commit
after cleaning up the mess.

Change-Id: I63b69273cac194163b784211474ec2ff77bd7959
Reviewed-on: http://review.couchbase.org/13510
Reviewed-by: Trond Norbye <trond.norbye@gmail.com>
Reviewed-by: Michael Wiederhold <mike@couchbase.com>
Tested-by: Matt Ingenthron <matt@couchbase.com>
  • Loading branch information...
1 parent 5018474 commit 66367ecb910aae124bd0f6bc06815a23e095966e @ingenthr ingenthr committed with ingenthr Feb 23, 2012
@@ -54,6 +54,7 @@ public void initialize() {
message.setOpcode(TapOpcode.REQUEST);
message.setFlags(TapRequestFlag.BACKFILL);
message.setFlags(TapRequestFlag.SUPPORT_ACK);
+ message.setFlags(TapRequestFlag.FIX_BYTEORDER);
if (id != null) {
message.setName(id);
} else {
@@ -1,6 +1,6 @@
/**
* Copyright (C) 2006-2009 Dustin Sallings
- * Copyright (C) 2009-2011 Couchbase, Inc.
+ * Copyright (C) 2009-2012 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,6 +29,7 @@
import net.spy.memcached.ops.OperationState;
import net.spy.memcached.ops.TapOperation;
import net.spy.memcached.tapmessage.RequestMessage;
+import net.spy.memcached.tapmessage.TapRequestFlag;
/**
* Implementation of a custom tap operation.
@@ -47,6 +48,7 @@
@Override
public void initialize() {
+ message.setFlags(TapRequestFlag.FIX_BYTEORDER);
if (id != null) {
message.setName(id);
} else {
@@ -52,6 +52,7 @@ public void initialize() {
message.setOpcode(TapOpcode.REQUEST);
message.setFlags(TapRequestFlag.DUMP);
message.setFlags(TapRequestFlag.SUPPORT_ACK);
+ message.setFlags(TapRequestFlag.FIX_BYTEORDER);
if (id != null) {
message.setName(id);
} else {
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2009-2011 Couchbase, Inc.
+ * Copyright (C) 2009-2012 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -248,6 +248,13 @@ protected int decodeInt(byte[] data, int i) {
| (data[i + 3] & 0xff);
}
+ protected int decodeIntHostOrder(byte[] data, int i) {
+ return (data[i] & 0xff)
+ | (data[i + 1] & 0xff) << 8
+ | (data[i + 2] & 0xff) << 16
+ | (data[i + 3] & 0xff) << 24;
+ }
+
protected long decodeLong(byte[] data, int i) {
return (data[i] & 0xffL) << 56
| (data[i + 1] & 0xffL) << 48
@@ -80,7 +80,12 @@ public ResponseMessage(byte[] b) {
}
if (opcode.equals(TapOpcode.MUTATION)) {
- itemflags = decodeInt(b, ITEM_FLAGS_OFFSET);
+ if (flags.contains(TapResponseFlag.TAP_FLAG_NETWORK_BYTE_ORDER)) {
+ itemflags = decodeInt(b, ITEM_FLAGS_OFFSET);
+ } else {
+ // handles Couchbase bug MB-4834
+ itemflags = decodeIntHostOrder(b, ITEM_FLAGS_OFFSET);
+ }
itemexpiry = decodeInt(b, ITEM_EXPIRY_OFFSET);
vbucketstate = 0;
revid = new byte[engineprivate];

0 comments on commit 66367ec

Please sign in to comment.