Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

#### 2.0.0

- Do not set beta protocol flag when using v5 (CASSGO-88)

#### 2.0.0-rc1

- Cassandra version unmarshal fix (CASSGO-49)
Expand Down
16 changes: 15 additions & 1 deletion conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,21 @@ func (c *Conn) execInternal(ctx context.Context, req frameBuilder, tracer Tracer
defer c.releaseStream(call)

if v := resp.framer.header.version.version(); v != c.version {
return nil, NewErrProtocol("unexpected protocol version in response: got %d expected %d", v, c.version)
errProtocol := NewErrProtocol("unexpected protocol version in response: got %d expected %d", v, c.version)
responseFrame, err := resp.framer.parseFrame()
if err != nil {
c.logger.Warning("Framer error while attempting to parse potential protocol error.",
newLogFieldError("err", err))
return nil, errProtocol
}
//goland:noinspection GoTypeAssertionOnErrors
errFrame, isErrFrame := responseFrame.(errorFrame)
if !isErrFrame || errFrame.Code() != ErrCodeProtocol {
return nil, errProtocol
}
return nil, NewErrProtocol("%w", &protocolError{
errFrame,
})
}

return resp.framer, nil
Expand Down
31 changes: 27 additions & 4 deletions control.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,34 @@ func shuffleHosts(hosts []*HostInfo) []*HostInfo {

// this is going to be version dependant and a nightmare to maintain :(
var protocolSupportRe = regexp.MustCompile(`the lowest supported version is \d+ and the greatest is (\d+)$`)
var betaProtocolRe = regexp.MustCompile(`Beta version of the protocol used \(.*\), but USE_BETA flag is unset`)

func parseProtocolFromError(err error) int {
errStr := err.Error()

var errProtocol ErrProtocol
if errors.As(err, &errProtocol) {
err = errProtocol.error
}

// I really wish this had the actual info in the error frame...
matches := protocolSupportRe.FindAllStringSubmatch(err.Error(), -1)
matches := betaProtocolRe.FindAllStringSubmatch(errStr, -1)
if len(matches) == 1 {
var protoErr *protocolError
if errors.As(err, &protoErr) {
version := protoErr.frame.Header().version.version()
if version > 0 {
return int(version - 1)
}
}
return 0
}

matches = protocolSupportRe.FindAllStringSubmatch(errStr, -1)
if len(matches) != 1 || len(matches[0]) != 2 {
if verr, ok := err.(*protocolError); ok {
return int(verr.frame.Header().version.version())
var protoErr *protocolError
if errors.As(err, &protoErr) {
return int(protoErr.frame.Header().version.version())
}
return 0
}
Expand All @@ -223,11 +244,13 @@ func parseProtocolFromError(err error) int {
return max
}

const highestProtocolVersionSupported = 5

func (c *controlConn) discoverProtocol(hosts []*HostInfo) (int, error) {
hosts = shuffleHosts(hosts)

connCfg := *c.session.connCfg
connCfg.ProtoVersion = 5 // TODO: define maxProtocol
connCfg.ProtoVersion = highestProtocolVersionSupported

handler := connErrorHandlerFn(func(c *Conn, err error, closed bool) {
// we should never get here, but if we do it means we connected to a
Expand Down
3 changes: 0 additions & 3 deletions frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,6 @@ func newFramer(compressor Compressor, version byte, r *RegisteredTypes) *framer
if compressor != nil {
flags |= flagCompress
}
if version == protoVersion5 {
flags |= flagBetaProtocol
}

version &= protoVersionMask

Expand Down