From 5e4e1ac0ecf4e3835f7b8e0a1d5e6b13007ba323 Mon Sep 17 00:00:00 2001 From: shortendarragh-mt Date: Mon, 21 Sep 2020 11:48:09 -0700 Subject: [PATCH 1/2] fix KetamaNodeLocator, CAS uint overflow --- Memcached/NodeLocators/KetamaNodeLocator.cs | 11 +++++++++++ Memcached/Protocol/Text/TextOperationFactory.cs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Memcached/NodeLocators/KetamaNodeLocator.cs b/Memcached/NodeLocators/KetamaNodeLocator.cs index e203d68..5e4b868 100644 --- a/Memcached/NodeLocators/KetamaNodeLocator.cs +++ b/Memcached/NodeLocators/KetamaNodeLocator.cs @@ -84,6 +84,17 @@ void INodeLocator.Initialize(IList nodes) // 01 02 03 04 05 06 07 // server will be stored with keys 0x07060504 & 0x03020100 var address = currentNode.EndPoint.ToString(); + // PeteE: Other libketama-comaptible clients (libmemcached, node, pylibmc) ignore the port number + // when calculating the hash if the default port (11211) is used. + // If using a non-standard port, we use the full hostname:port + // Examples: + // libmemcached: https://bazaar.launchpad.net/~tangent-trunk/libmemcached/1.2/view/head:/libmemcached/hosts.cc#L293 + // node-hashring: https://github.com/3rd-Eden/node-hashring/blob/master/index.js#L138 + + if (currentNode.EndPoint.Port == MemcachedDefaultPort) + { + address = currentNode.EndPoint.Address.ToString(); + } for (var mutation = 0; mutation < KetamaNodeLocator.ServerAddressMutations / partCount; mutation++) { var data = hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(address + "-" + mutation)); diff --git a/Memcached/Protocol/Text/TextOperationFactory.cs b/Memcached/Protocol/Text/TextOperationFactory.cs index cbf18ed..b28debd 100644 --- a/Memcached/Protocol/Text/TextOperationFactory.cs +++ b/Memcached/Protocol/Text/TextOperationFactory.cs @@ -20,7 +20,7 @@ IStoreOperation IOperationFactory.Store(StoreMode mode, string key, CacheItem va if (cas == 0) return new StoreOperation(mode, key, value, expires); - return new CasOperation(key, value, expires, (uint)cas); + return new CasOperation(key, value, expires, cas); } IDeleteOperation IOperationFactory.Delete(string key, ulong cas) From 3ddac63ffe37785c09b5d44a2bbfc5c5fdb8b95b Mon Sep 17 00:00:00 2001 From: shortendarragh-mt Date: Mon, 21 Sep 2020 13:25:11 -0700 Subject: [PATCH 2/2] Fix ketama node locator by ignoring port number when default port is used --- Memcached/NodeLocators/KetamaNodeLocator.cs | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Memcached/NodeLocators/KetamaNodeLocator.cs b/Memcached/NodeLocators/KetamaNodeLocator.cs index 5e4b868..48e7732 100644 --- a/Memcached/NodeLocators/KetamaNodeLocator.cs +++ b/Memcached/NodeLocators/KetamaNodeLocator.cs @@ -3,6 +3,7 @@ using System.Text; using System.Threading; using System.Collections.Generic; +using System.Net; using System.Security.Cryptography; namespace Enyim.Caching.Memcached @@ -13,6 +14,7 @@ namespace Enyim.Caching.Memcached public sealed class KetamaNodeLocator : INodeLocator { static int ServerAddressMutations { get; } = 160; + static int MemcachedDefaultPort { get; } = 11211; static Dictionary> Factories { get; } = new Dictionary>(StringComparer.OrdinalIgnoreCase) { { "md5", () => MD5.Create() }, @@ -84,17 +86,16 @@ void INodeLocator.Initialize(IList nodes) // 01 02 03 04 05 06 07 // server will be stored with keys 0x07060504 & 0x03020100 var address = currentNode.EndPoint.ToString(); - // PeteE: Other libketama-comaptible clients (libmemcached, node, pylibmc) ignore the port number - // when calculating the hash if the default port (11211) is used. - // If using a non-standard port, we use the full hostname:port - // Examples: - // libmemcached: https://bazaar.launchpad.net/~tangent-trunk/libmemcached/1.2/view/head:/libmemcached/hosts.cc#L293 - // node-hashring: https://github.com/3rd-Eden/node-hashring/blob/master/index.js#L138 - - if (currentNode.EndPoint.Port == MemcachedDefaultPort) - { - address = currentNode.EndPoint.Address.ToString(); - } + // Other libketama-comaptible clients (libmemcached, node, pylibmc) ignore the port number + // when calculating the hash if the default port (11211) is used. + // If using a non-standard port, we use the full hostname:port + // Examples: + // libmemcached: https://bazaar.launchpad.net/~tangent-trunk/libmemcached/1.2/view/head:/libmemcached/hosts.cc#L293 + // node-hashring: https://github.com/3rd-Eden/node-hashring/blob/master/index.js#L138 + if (((IPEndPoint)currentNode.EndPoint).Port == MemcachedDefaultPort) + { + address = ((IPEndPoint)currentNode.EndPoint).Address.ToString(); + } for (var mutation = 0; mutation < KetamaNodeLocator.ServerAddressMutations / partCount; mutation++) { var data = hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(address + "-" + mutation));