Skip to content

SniEndPoint.__lt__ compares its own _server_name instead of the other endpoint's #1016

Description

@nikagra

At cassandra/connection.py:313-315 on master, the right-hand tuple is built from self._server_name rather than other._server_name:

@total_ordering
class SniEndPoint(EndPoint):
    ...
    def __lt__(self, other):
        return ((self.address, self.port, self._server_name) <
                (other.address, other.port, self._server_name))

__eq__ and __hash__ just above it both use other._server_name, so this looks like a copy-paste slip rather than an intended asymmetry.

Consequence. Two SNI endpoints that share a proxy address and port but differ by server name compare as neither less nor greater: the third element of both tuples is the same object, so the comparison falls through to equality on the first two. a < b and b < a are both False for endpoints __eq__ considers different. SniEndPoint carries @total_ordering, so the derived >, <= and >= inherit the same result, and sorted() over a list of such endpoints is not well defined — the order depends on where Timsort happens to place each item.

This is the normal shape for an SNI deployment: one proxy address and port, many server names.

Repro

from cassandra.connection import SniEndPoint

a = SniEndPoint("proxy.example", "node-a", 9042)
b = SniEndPoint("proxy.example", "node-b", 9042)

assert a != b
print(a < b, b < a, a >= b, b >= a)   # False False True True

Fix. other._server_name in the right-hand tuple.

Not introduced by any open PR; it dates to 9b145cf9 (Add SNIEndPoint support). Noticed while reviewing #789, which adds _default_tls_session_cache_key to the same class but does not touch this method.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions