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

How to share state between servers #264

Closed
bocajim opened this issue Jun 16, 2020 · 5 comments
Closed

How to share state between servers #264

bocajim opened this issue Jun 16, 2020 · 5 comments

Comments

@bocajim
Copy link
Contributor

bocajim commented Jun 16, 2020

So I'm trying to migrate to using this DTLS library, and I need to be able to serialize and preserve the state of the DTLS connections.

Is the flow to use the Export method on a connection to get the state, and then Resume to resume it?

What would the recommended flow be for an application?

On each packet received export and save the state, and then on server startup retrieve the saved states and resume each of them?

I can build it into an example and submit a pull request if you point me in the right direction.

@Sean-Der
Copy link
Member

Hey @bocajim!

Great work on your DTLS implementation. You inspired me a lot, convinced me that it was possible to implement DTLS in Go :) Even though if this cost me a month of my life reading OpenSSL code :p

We have State

You can pull this via Export and start up again with Resume

We should have tests for it. The developer who contributed it is also still active, so if you hit anything should be easy to fix. Really excited to have you involved :)

@igolaizola
Copy link
Member

Hi @bocajim! Nice to see you here!

On v2 we changed the API to use ConnectionState instead of Export.
There are some examples on resume_test.go

Is the flow to use the Export method on a connection to get the state, and then Resume to resume it?

That's correct. But you should think first if performing a new handshake suits better for you or not. If due to resource constraints (latency/hardware/other) a new handshake is not viable, then you can go with this export/resume approach.

What would the recommended flow be for an application?
On each packet received export and save the state, and then on server startup retrieve the saved states and resume each of them?

You could save the the state on every packet received/sent. Or if you have an app layer with a request/response sequence, once it has finished.

A good recommendation could be to save these states on RAM memory and only persist them to a DB or similar during a graceful shutdown in order to restore them on a service startup.

@bocajim
Copy link
Contributor Author

bocajim commented Jun 16, 2020

Thanks for the feedback, last question on this, is there a way to do a "lazy load" of the State when a packet is received from a previously unknown remote address? Use case is I have 25,000,000 concurrent DTLS sessions that send packets 4 times per day, so I don't want to keep all 25,000,000 sessions in memory, I want to use a cache like redis to hold them. When a packet comes in I want to retrieve the state from redis instead of from memory then use it.

If it doesn't exist, I'm thinking of a callback that can be registered when a packet is received to try to retrieve the state if its not already in the in-memory map.

@igolaizola
Copy link
Member

Use case is I have 25,000,000 concurrent DTLS sessions that send packets 4 times per day, so I don't want to keep all 25,000,000 sessions in memory, I want to use a cache like redis to hold them.

This sounds like a lot of IoT devices connected! I am working on a similar architecture but with a higher data frecuency. Our first approach will be to keep sessions in memory and use persistent storage to recover them (for example after a service graceful shutdown).

is there a way to do a "lazy load" of the State when a packet is received from a previously unknown remote address?

There isn't something like this on the library...

If it doesn't exist, I'm thinking of a callback that can be registered when a packet is received to try to retrieve the state if its not already in the in-memory map.

That will be your best choice. When this callback runs you could:

  • load the state (from redis or memory) based on a connection ID
  • create a net.Conn wrapper that includes the incoming packet
  • call dtls.Resume with the loaded state and wrapped conn
  • call dtlsConn.Read() to obtain decrypted data
  • save the new state back on redis/memory

@Sean-Der
Copy link
Member

I am going to resolve this.

If we need more/different APIs around state suspension/resumption always happy to explore it!

@Sean-Der Sean-Der closed this as not planned Won't fix, can't repro, duplicate, stale May 21, 2024
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

No branches or pull requests

3 participants