Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add handshake validators #308

Merged
merged 10 commits into from
May 24, 2023
Merged

Add handshake validators #308

merged 10 commits into from
May 24, 2023

Conversation

reinaldooli
Copy link
Collaborator

@reinaldooli reinaldooli commented May 12, 2023

Context

Sometimes, it is mandatory that the clients met some requirements before being allowed to connect.

In order to achieve this, SessionPool now has a function AddHandshakeValidator and all the added validators will run as soon as the handshake is processed.

With this, clients can send the requirements through handshake parameters, and it can be validated before establishing the connection.

for _, fun := range a.GetSession().GetHandshakeValidators() {
if err := fun(handshakeData); err != nil {
a.SetStatus(constants.StatusClosed)
return fmt.Errorf("Handshake validation failed: %w. Id=%d", err, a.GetSession().ID())
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to return specific error codes to clients if the validation fail? That'd be very useful to handle forced updates and server maintenance, for example.

Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't the err here already the one returned by the handshake validator? And if so it is something you have control over already, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In this step, clients already received a message about the handshake.
Any error that may occur after sending the handshake response, just close the session.

Copy link
Member

Choose a reason for hiding this comment

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

Hum, I see. I guess it'd be best to return the handshake response only after validation.

From the client perspective, getting a sudden connection close without reason might be very confusing during development, wouldn't it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes! I've changed the process to send more comprehensive messages to clients. This first version should not break anything on the client side, but it won't send any information about the error to clients, just a 400 code (Bad Request). A further (maybe breaking) change can be addressed to provide to client a clearer message about what happened in the server.

@@ -227,6 +227,13 @@ func (h *HandlerService) processPacket(a agent.Agent, p *packet.Packet) error {
return fmt.Errorf("Invalid handshake data. Id=%d", a.GetSession().ID())
}

for _, fun := range a.GetSession().GetHandshakeValidators() {
if err := fun(handshakeData); err != nil {
Copy link
Collaborator

@vitorbaraujo vitorbaraujo May 12, 2023

Choose a reason for hiding this comment

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

The way it is, an error is returned when the first validation fails, ignoring following validations. Would it be interesting to run all validators and return an error if any one of them fails (possibly bundling validation messages)? This would provide less back and forth in case multiple validations are to fail.

Copy link
Collaborator

@vitorbaraujo vitorbaraujo May 12, 2023

Choose a reason for hiding this comment

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

To be honest, I'm not sure if this use-case if that valuable, though.

Copy link
Contributor

Choose a reason for hiding this comment

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

For simplicity sake's I say lets keep the way it is right now. The end result is the same whether multiple or only one validator failed.

Copy link
Contributor

@felipejfc felipejfc left a comment

Choose a reason for hiding this comment

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

Did you test with no handshake validators added? I missed where you are initializing the array

@@ -227,6 +227,13 @@ func (h *HandlerService) processPacket(a agent.Agent, p *packet.Packet) error {
return fmt.Errorf("Invalid handshake data. Id=%d", a.GetSession().ID())
}

for _, fun := range a.GetSession().GetHandshakeValidators() {
if err := fun(handshakeData); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

For simplicity sake's I say lets keep the way it is right now. The end result is the same whether multiple or only one validator failed.

for _, fun := range a.GetSession().GetHandshakeValidators() {
if err := fun(handshakeData); err != nil {
a.SetStatus(constants.StatusClosed)
return fmt.Errorf("Handshake validation failed: %w. Id=%d", err, a.GetSession().ID())
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't the err here already the one returned by the handshake validator? And if so it is something you have control over already, right?

@coveralls
Copy link

coveralls commented May 15, 2023

Pull Request Test Coverage Report for Build 5068848464

  • 72 of 94 (76.6%) changed or added relevant lines in 4 files are covered.
  • 11 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.02%) to 62.113%

Changes Missing Coverage Covered Lines Changed/Added Lines %
session/session.go 23 24 95.83%
service/handler.go 12 18 66.67%
agent/agent.go 27 42 64.29%
Files with Coverage Reduction New Missed Lines %
modules/binary.go 2 73.91%
agent/agent.go 9 75.65%
Totals Coverage Status
Change from base Build 5034146394: -0.02%
Covered Lines: 4769
Relevant Lines: 7678

💛 - Coveralls

@felipejfc
Copy link
Contributor

felipejfc commented May 19, 2023

@reinaldooli please update the docs with HandshakeValidators information
Also, it would be nice to have some operational metrics being emmited for handshake successes and failures

@felipejfc felipejfc force-pushed the main branch 3 times, most recently from 1d5b0cf to 98580b5 Compare May 20, 2023 21:04
Copy link
Member

@felippeduran felippeduran left a comment

Choose a reason for hiding this comment

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

Other the the comment I raised, the rest looks good. I also agree with the conclusion in @vitorbaraujo's thread.

However, I believe it'd be important to resolve my thread before merging.

@reinaldooli reinaldooli merged commit 04e8c01 into main May 24, 2023
@reinaldooli reinaldooli deleted the feature/handshake-validators branch May 24, 2023 16:42
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.

5 participants