Exit registration flow

Current procedure

  • Router is shipped with a list of exits, this includes their public key, mesh ip, and other metadata
  • User turns router on
  • Their router continuously queries getinfo endpoint for all exits in the New state.
  • The exit responds with info needed for connection that are general to all clients. When the client receives this info it sets the exit listing to the GotInfo state
  • Their router continuously attempts to sign up to all exits in the GotInfo state, sending their own pub key and other metadata.
  • If an exit accepts them, it responds with client specific connection details, and the exit listing is set to the Accepted state
  • If an exit rejects them, the exit listing is set to the Rejected state

Adding email confirmation

If we don’t have email confirmation, then there’s no in getting an email address at all. If we do have email confirmation it should involve the exit sending an email to the address, containing a code which needs to be entered into the dashboard.

Procedure with email conf

  • Router is shipped with a list of exits, this includes their public key, mesh ip, and other metadata
  • User turns router on
  • Their router continuously queries getinfo endpoint for all exits in the New state.
  • If the user is not in a region the exit accepts, it sends back a rejected response, and the router sets the exit listing to Rejected. If the user is in a region the exit accepts, the exit responds with info needed for connection that are general to all clients. When the client receives this info it sets the exit listing to the GotInfo state.
  • Their router continuously attempts to sign up to all exits in the GotInfo state, sending their own pub key and other metadata, including email.
  • The exit sends an email to the address, with a one time code
  • The user checks their email by going to a local library or post office with internet access and writes down the code, then goes home and enters it into the router.
  • Once it has the code, the router sends it to the exit.
  • If an exit accepts them, it responds with client specific connection details, and the exit listing is set to the Accepted state, and sets an accepted message
  • If an exit rejects them, the exit listing is set to the Rejected state, and sets a rejected message.

If we automatically attempt to sign up to all exits all the time, then the user will get a crapload of emails. So a possible solution would be to ship with all exits in the Disabled state. When the user decides to use an exit, they take it out of the Disabled state, and the router attempts to do the above flow.

@kindiana does this look right?

@Jehan the current procedure looks correct, new changes seem reasonable as well

I want to brainstorm a different flow, just because the existing one is kind of different from how people expect stuff like this to work. For instance, needing to set a exit back into state New to re-attempt registration. Most people think of registration as being a deliberate event.

  • Router is shipped with a list of exits, this includes their public key, mesh ip, and other metadata
  • User turns router on
  • Their router slowly polls getinfo endpoint for all exits.
  • If the user is not in a region the exit accepts, it sends back a rejected response, and the router sets the exit listing to NonViable. If the user is in a region the exit accepts, the exit responds with info needed for connection that are general to all clients. When the client receives this info it sets the exit listing to the GotInfo state.
  • The user sees a list of exits where only exits which are not New or NonViable are able to be selected.
  • When they decide which exit to try to sign up with, they click on it.
  • The router calls the register endpoint and the exit listing goes into Pending state.
  • The exit sends an email to the address, with a one time code
  • The user checks their email by going to a local library or post office with internet access and writes down the code, then goes home and enters it into the router.
  • Once it has the code, the router sends it to the exit.
  • If an exit accepts them, it responds with client specific connection details, and the exit listing is set to the Accepted state, and sets an accepted message
  • If an exit rejects them, the exit listing is set to the Rejected state, and sets a rejected message.
1 Like

This flow looks pretty neat! And if an exit owner wants they could even skip the internet caffé part and just set up an SMS gate to send the code to the client’s phone. We roughlyt talked over with @kindiana the changes needed in our codebase to implement this, and it shouldn’t be too dramatic.

@drozdziak1 @Jehan @ttk2

Spec for exit registration upgrade

Common

  • Adds new enum varient to ExitState: NonViable

Exit client

  • Default behavior
    • Change exit_general_details_request to accept both a ExitDetails from the server as well as a new wrapper type (maybe ExitInfo?) which has Option<ExitDetails> and a viable bool
    • Add new field description to ExitServer (no corresponding exit side changes required)
  • Future behavior
    • Query new endpoint for connection status if in state Registered, get back some sort of status struct which can tell the client to retry the registration process or go all the way back to New

Exit Server

  • Default behavior
    • Add endpoint for connection status
    • Add email verification (pending state + one time code + new database field) (IMO this should be a separate issue, as it has no backwards compat implications)
  • Future behavior
    • Change get_exit_info to return ExitInfo
    • Change geoip response from denied to nonviable

Another change which I am thinking of (which isn’t really an breaking API change, except for the dashboard) is to store the exit state information as a enum with different values in each varient instead of a detatched state and optional fields for all the different data peices. This exposes a stronger contract to the dashboard API and makes sure it is impossible to get into an inconsistant state (where we think we have information but we don’t, or the other way around.

I think that’s a great idea