Skip to content

Conversation

@enocom
Copy link
Member

@enocom enocom commented Jun 14, 2022

Fixes #225.

@enocom enocom requested a review from a team June 14, 2022 18:10
dialer.go Outdated
// SyscallConn supports a connection check in the MySQL driver by delegating to
// the underlying non-TLS net.Conn.
func (i *instrumentedConn) SyscallConn() (syscall.RawConn, error) {
sconn := i.rawConn.(syscall.Conn)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this break on windows?

Copy link
Member Author

@enocom enocom Jun 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I'll add a unit test to make sure we have support in either case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the MySQL driver doesn't have support for Windows here: https://github.com/go-sql-driver/mysql/blob/ad9fa14acdcf7d0533e7fbe58728f3d216213ade/conncheck_dummy.go#L9. What would your expectation be?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this so it won't panic if the type assertion fails. Separately, this builds on Windows with the unit test, so I think we're good.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just expect it not to panic. (Parity to go mysql should be good)

humm I don't think returning an error will work with go mysql's current implementation. it will always trigger driver.ErrBadConn.

func (mc *mysqlConn) writePacket(data []byte) error {
	...
		if err == nil && mc.cfg.CheckConnLiveness {
			err = connCheck(conn)
		}
		if err != nil {
			errLog.Print("closing bad idle connection: ", err)
			mc.Close()
			return driver.ErrBadConn
		}
         ...

where connCheck():

func connCheck(conn net.Conn) error {
	...
	rawConn, err := sysConn.SyscallConn()
	if err != nil {
		return err
	}
	...
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take another look at this and see what we can do. Thanks for all your help on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the platforms that don't support the call won't use connCheck: https://github.com/go-sql-driver/mysql/blob/ad9fa14acdcf7d0533e7fbe58728f3d216213ade/conncheck_dummy.go#L16

So it seems like it's probably fine to return an error, since if it is being used something probably wrong?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s my understanding as well. @Gentoli what do you think?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I did not realize // +build is built-in to golang. Both with or without the check on the cast should work.

@enocom enocom changed the title fix: support MySQL diver's conn check. fix: support MySQL driver’s conn check. Jun 15, 2022
@enocom enocom requested a review from kurtisvg June 15, 2022 03:01
@enocom enocom merged commit 4b48e3b into main Jun 16, 2022
@enocom enocom deleted the conn-check branch June 16, 2022 19:42
enocom added a commit that referenced this pull request Nov 23, 2022
This reverts commit 4b48e3b.

This fix was incorrect. The connection to the Cloud SQL instance is a
TLS connection. A recent version of Go made it possible to access the
underlying net.Conn, but noted: "writing to or reading from this
connection directly will corrupt the TLS session." [1] The change here made
it possible for the MySQL driver to inadvertenly read from the
underlying connection. [2] Instead, we should be attempting to read from
the TLS connection without corrupting it.

[1] https://pkg.go.dev/crypto/tls#Conn.NetConn.
[2] https://github.com/go-sql-driver/mysql/blob/ad9fa14acdcf7d0533e7fbe58728f3d216213ade/conncheck.go#L34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for checking conn health with MySQL Client

3 participants