diff --git a/documentation/sphinx/source/api-error-codes.rst b/documentation/sphinx/source/api-error-codes.rst index 7dac09bd9c..7c06dbb6df 100644 --- a/documentation/sphinx/source/api-error-codes.rst +++ b/documentation/sphinx/source/api-error-codes.rst @@ -176,8 +176,6 @@ FoundationDB may return the following error codes from API functions. If you nee +-----------------------------------------------+-----+--------------------------------------------------------------------------------+ | unknown_tenant | 2137| Tenant is not available from this server | +-----------------------------------------------+-----+--------------------------------------------------------------------------------+ -| illegal_tenant_access | 2138| Tenant information mismatch | -+-----------------------------------------------+-----+--------------------------------------------------------------------------------+ | api_version_unset | 2200| API version is not set | +-----------------------------------------------+-----+--------------------------------------------------------------------------------+ | api_version_already_set | 2201| API version may be set only once | diff --git a/fdbserver/CommitProxyServer.actor.cpp b/fdbserver/CommitProxyServer.actor.cpp index 2b8a6079de..2ced6949ef 100644 --- a/fdbserver/CommitProxyServer.actor.cpp +++ b/fdbserver/CommitProxyServer.actor.cpp @@ -279,13 +279,32 @@ bool verifyPrefix(ProxyCommitData* const commitData, const CommitTransactionRequ for (auto& m : req.transaction.mutations) { if (m.param1 != metadataVersionKey) { if (!m.param1.startsWith(tenantPrefix)) { + TraceEvent(SevWarnAlways, "TenantPrefixMismatch") + .suppressFor(60) + .detail("Prefix", tenantPrefix.toHexString()) + .detail("Key", m.param1.toHexString()) + .detail("KeyType", "Key"); return false; } + if (m.type == MutationRef::ClearRange && !m.param2.startsWith(tenantPrefix)) { + TraceEvent(SevWarnAlways, "TenantPrefixMismatch") + .suppressFor(60) + .detail("Prefix", tenantPrefix.toHexString()) + .detail("Key", m.param2.toHexString()) + .detail("KeyType", "ClearRangeKey"); return false; - } else if (m.type != MutationRef::SetVersionstampedKey) { - // TODO: How should this be handled? - // Maybe skip checking this for now? If so, fall-through. + } else if (m.type == MutationRef::SetVersionstampedKey) { + uint8_t* key = const_cast(m.param1.begin()); + int* offset = reinterpret_cast(&key[m.param1.size() - 4]); + if (*offset <= tenantPrefix.size()) { + TraceEvent(SevWarnAlways, "TenantPrefixMismatch") + .suppressFor(60) + .detail("Prefix", tenantPrefix.toHexString()) + .detail("Key", m.param1.toHexString()) + .detail("KeyType", "VersionstampedKey"); + return false; + } } } } @@ -293,6 +312,11 @@ bool verifyPrefix(ProxyCommitData* const commitData, const CommitTransactionRequ for (auto& rc : req.transaction.read_conflict_ranges) { if (rc.begin != metadataVersionKey && (!rc.begin.startsWith(tenantPrefix) || !rc.end.startsWith(tenantPrefix))) { + TraceEvent(SevWarnAlways, "TenantPrefixMismatch") + .suppressFor(60) + .detail("Prefix", tenantPrefix.toHexString()) + .detail("BeginKey", rc.begin.toHexString()) + .detail("EndKey", rc.end.toHexString()); return false; } } @@ -300,6 +324,11 @@ bool verifyPrefix(ProxyCommitData* const commitData, const CommitTransactionRequ for (auto& wc : req.transaction.write_conflict_ranges) { if (wc.begin != metadataVersionKey && (!wc.begin.startsWith(tenantPrefix) || !wc.end.startsWith(tenantPrefix))) { + TraceEvent(SevWarnAlways, "TenantPrefixMismatch") + .suppressFor(60) + .detail("Prefix", tenantPrefix.toHexString()) + .detail("BeginKey", wc.begin.toHexString()) + .detail("EndKey", wc.end.toHexString()); return false; } } @@ -358,7 +387,6 @@ ACTOR Future commitBatcher(ProxyCommitData* commitData, if (!verifyPrefix(commitData, req)) { ++commitData->stats.txnCommitErrors; req.reply.sendError(illegal_tenant_access()); - TraceEvent(SevWarnAlways, "TenantPrefixMismatch").suppressFor(60); continue; } diff --git a/flow/error_definitions.h b/flow/error_definitions.h index e24d840602..7147164749 100755 --- a/flow/error_definitions.h +++ b/flow/error_definitions.h @@ -226,7 +226,7 @@ ERROR( invalid_tenant_name, 2134, "Tenant name cannot begin with \\xff"); ERROR( tenant_prefix_allocator_conflict, 2135, "The database already has keys stored at the prefix allocated for the tenant"); ERROR( tenants_disabled, 2136, "Tenants have been disabled in the cluster"); ERROR( unknown_tenant, 2137, "Tenant is not available from this server") -ERROR( illegal_tenant_access, 2138, "Tenant information mismatch") +ERROR( illegal_tenant_access, 2138, "Illegal tenant access") // 2200 - errors from bindings and official APIs ERROR( api_version_unset, 2200, "API version is not set" )