mirror of
https://github.com/coder/coder.git
synced 2026-06-03 04:58:23 +00:00
bf78966256
Undoes a lot of the changes in 5319d47dfa
Keeps the `netns.SetCoderSoftIsolation()` call, but always sets it to
`true` when using a TUN device.
293 lines
8.3 KiB
Protocol Buffer
293 lines
8.3 KiB
Protocol Buffer
syntax = "proto3";
|
||
option go_package = "github.com/coder/coder/v2/vpn";
|
||
option csharp_namespace = "Coder.Desktop.Vpn.Proto";
|
||
|
||
import "google/protobuf/timestamp.proto";
|
||
import "google/protobuf/duration.proto";
|
||
|
||
package vpn;
|
||
|
||
// The CoderVPN protocol operates over a bidirectional stream between a "manager" and a "tunnel."
|
||
// The manager is part of the Coder Desktop application and written in OS native code. It handles
|
||
// configuring the VPN and displaying status to the end user. The tunnel is written in Go and
|
||
// handles operating the actual tunnel, including reading and writing packets, & communicating with
|
||
// the Coder server control plane.
|
||
|
||
|
||
// RPC allows a very simple unary request/response RPC mechanism. The requester generates a unique
|
||
// msg_id which it sets on the request, the responder sets response_to that msg_id on the response
|
||
// message
|
||
message RPC {
|
||
uint64 msg_id = 1;
|
||
uint64 response_to = 2;
|
||
}
|
||
|
||
// ManagerMessage is a message from the manager (to the tunnel).
|
||
message ManagerMessage {
|
||
RPC rpc = 1;
|
||
oneof msg {
|
||
GetPeerUpdate get_peer_update = 2;
|
||
NetworkSettingsResponse network_settings = 3;
|
||
StartRequest start = 4;
|
||
StopRequest stop = 5;
|
||
}
|
||
}
|
||
|
||
// TunnelMessage is a message from the tunnel (to the manager).
|
||
message TunnelMessage {
|
||
RPC rpc = 1;
|
||
oneof msg {
|
||
Log log = 2;
|
||
PeerUpdate peer_update = 3;
|
||
NetworkSettingsRequest network_settings = 4;
|
||
StartResponse start = 5;
|
||
StopResponse stop = 6;
|
||
}
|
||
}
|
||
|
||
// ClientMessage is a message from the client (to the service). Windows only.
|
||
message ClientMessage {
|
||
RPC rpc = 1;
|
||
oneof msg {
|
||
StartRequest start = 2;
|
||
StopRequest stop = 3;
|
||
StatusRequest status = 4;
|
||
}
|
||
}
|
||
|
||
// ServiceMessage is a message from the service (to the client). Windows only.
|
||
message ServiceMessage {
|
||
RPC rpc = 1;
|
||
oneof msg {
|
||
StartResponse start = 2;
|
||
StopResponse stop = 3;
|
||
Status status = 4; // either in reply to a StatusRequest or broadcasted
|
||
StartProgress start_progress = 5; // broadcasted during startup (used exclusively by Windows)
|
||
}
|
||
}
|
||
|
||
// Log is a log message generated by the tunnel. The manager should log it to the system log. It is
|
||
// one-way tunnel -> manager with no response.
|
||
message Log {
|
||
enum Level {
|
||
// these are designed to match slog levels
|
||
DEBUG = 0;
|
||
INFO = 1;
|
||
WARN = 2;
|
||
ERROR = 3;
|
||
CRITICAL = 4;
|
||
FATAL = 5;
|
||
}
|
||
Level level = 1;
|
||
|
||
string message = 2;
|
||
repeated string logger_names = 3;
|
||
|
||
message Field {
|
||
string name = 1;
|
||
string value = 2;
|
||
}
|
||
repeated Field fields = 4;
|
||
}
|
||
|
||
// GetPeerUpdate asks for a PeerUpdate with a full set of data.
|
||
message GetPeerUpdate {}
|
||
|
||
// PeerUpdate is an update about workspaces and agents connected via the tunnel. It is generated in
|
||
// response to GetPeerUpdate (which dumps the full set). It is also generated on any changes (not in
|
||
// response to any request).
|
||
message PeerUpdate {
|
||
repeated Workspace upserted_workspaces = 1;
|
||
repeated Agent upserted_agents = 2;
|
||
repeated Workspace deleted_workspaces = 3;
|
||
repeated Agent deleted_agents = 4;
|
||
}
|
||
|
||
message Workspace {
|
||
bytes id = 1; // UUID
|
||
string name = 2;
|
||
|
||
enum Status {
|
||
UNKNOWN = 0;
|
||
PENDING = 1;
|
||
STARTING = 2;
|
||
RUNNING = 3;
|
||
STOPPING = 4;
|
||
STOPPED = 5;
|
||
FAILED = 6;
|
||
CANCELING = 7;
|
||
CANCELED = 8;
|
||
DELETING = 9;
|
||
DELETED = 10;
|
||
}
|
||
Status status = 3;
|
||
}
|
||
|
||
message Agent {
|
||
bytes id = 1; // UUID
|
||
string name = 2;
|
||
bytes workspace_id = 3; // UUID
|
||
repeated string fqdn = 4;
|
||
repeated string ip_addrs = 5;
|
||
// last_handshake is the primary indicator of whether we are connected to a peer. Zero value or
|
||
// anything longer than 5 minutes ago means there is a problem.
|
||
google.protobuf.Timestamp last_handshake = 6;
|
||
// If unset, a successful ping has not yet been made.
|
||
optional LastPing last_ping = 7;
|
||
}
|
||
|
||
message LastPing {
|
||
// latency is the RTT of the ping to the agent.
|
||
google.protobuf.Duration latency = 1;
|
||
// did_p2p indicates whether the ping was sent P2P, or over DERP.
|
||
bool did_p2p = 2;
|
||
// preferred_derp is the human readable name of the preferred DERP region,
|
||
// or the region used for the last ping, if it was sent over DERP.
|
||
string preferred_derp = 3;
|
||
// preferred_derp_latency is the last known latency to the preferred DERP
|
||
// region. Unset if the region does not appear in the DERP map.
|
||
optional google.protobuf.Duration preferred_derp_latency = 4;
|
||
}
|
||
|
||
// NetworkSettingsRequest is based on
|
||
// https://developer.apple.com/documentation/networkextension/nepackettunnelnetworksettings for
|
||
// macOS. It is a request/response message with response NetworkSettingsResponse
|
||
message NetworkSettingsRequest {
|
||
uint32 tunnel_overhead_bytes = 1;
|
||
uint32 mtu = 2;
|
||
|
||
message DNSSettings {
|
||
repeated string servers = 1;
|
||
repeated string search_domains = 2;
|
||
// domain_name is the primary domain name of the tunnel
|
||
string domain_name = 3;
|
||
repeated string match_domains = 4;
|
||
// match_domains_no_search specifies if the domains in the matchDomains list should not be
|
||
// appended to the resolver’s list of search domains.
|
||
bool match_domains_no_search = 5;
|
||
}
|
||
DNSSettings dns_settings = 3;
|
||
|
||
string tunnel_remote_address = 4;
|
||
|
||
message IPv4Settings {
|
||
repeated string addrs = 1;
|
||
repeated string subnet_masks = 2;
|
||
// router is the next-hop router in dotted-decimal format
|
||
string router = 3;
|
||
|
||
message IPv4Route {
|
||
string destination = 1;
|
||
string mask = 2;
|
||
// router is the next-hop router in dotted-decimal format
|
||
string router = 3;
|
||
}
|
||
repeated IPv4Route included_routes = 4;
|
||
repeated IPv4Route excluded_routes = 5;
|
||
}
|
||
IPv4Settings ipv4_settings = 5;
|
||
|
||
message IPv6Settings {
|
||
repeated string addrs = 1;
|
||
repeated uint32 prefix_lengths = 2;
|
||
|
||
message IPv6Route {
|
||
string destination = 1;
|
||
uint32 prefix_length = 2;
|
||
// router is the address of the next-hop
|
||
string router = 3;
|
||
}
|
||
repeated IPv6Route included_routes = 3;
|
||
repeated IPv6Route excluded_routes = 4;
|
||
}
|
||
IPv6Settings ipv6_settings = 6;
|
||
}
|
||
|
||
// NetworkSettingsResponse is the response from the manager to the tunnel for a
|
||
// NetworkSettingsRequest
|
||
message NetworkSettingsResponse {
|
||
bool success = 1;
|
||
string error_message = 2;
|
||
}
|
||
|
||
// StartRequest is a request from the manager to start the tunnel. The tunnel replies with a
|
||
// StartResponse.
|
||
message StartRequest {
|
||
int32 tunnel_file_descriptor = 1;
|
||
string coder_url = 2;
|
||
string api_token = 3;
|
||
// Additional HTTP headers added to all requests
|
||
message Header {
|
||
string name = 1;
|
||
string value = 2;
|
||
}
|
||
repeated Header headers = 4;
|
||
// Device ID from Coder Desktop
|
||
string device_id = 5;
|
||
// Device OS from Coder Desktop
|
||
string device_os = 6;
|
||
// Coder Desktop version
|
||
string coder_desktop_version = 7;
|
||
}
|
||
|
||
message StartResponse {
|
||
bool success = 1;
|
||
string error_message = 2;
|
||
}
|
||
|
||
// StartProgress is sent from the manager to the client to indicate the
|
||
// download/startup progress of the tunnel. This will be sent during the
|
||
// processing of a StartRequest before the StartResponse is sent.
|
||
//
|
||
// Note: this is currently a broadcasted message to all clients due to the
|
||
// inability to easily send messages to a specific client in the Speaker
|
||
// implementation. If clients are not expecting these messages, they
|
||
// should ignore them.
|
||
enum StartProgressStage {
|
||
Initializing = 0;
|
||
Downloading = 1;
|
||
Finalizing = 2;
|
||
}
|
||
message StartProgressDownloadProgress {
|
||
uint64 bytes_written = 1;
|
||
optional uint64 bytes_total = 2; // unknown in some situations
|
||
}
|
||
message StartProgress {
|
||
StartProgressStage stage = 1;
|
||
optional StartProgressDownloadProgress download_progress = 2; // only set when stage == Downloading
|
||
}
|
||
|
||
// StopRequest is a request from the manager to stop the tunnel. The tunnel replies with a
|
||
// StopResponse.
|
||
message StopRequest {}
|
||
|
||
// StopResponse is a response to stopping the tunnel. After sending this response, the tunnel closes
|
||
// its side of the bidirectional stream for writing.
|
||
message StopResponse {
|
||
bool success = 1;
|
||
string error_message = 2;
|
||
}
|
||
|
||
// StatusRequest is a request to get the status of the tunnel. The manager
|
||
// replies with a Status.
|
||
message StatusRequest {}
|
||
|
||
// Status is sent in response to a StatusRequest or broadcasted to all clients
|
||
// when the status changes.
|
||
message Status {
|
||
enum Lifecycle {
|
||
UNKNOWN = 0;
|
||
STARTING = 1;
|
||
STARTED = 2;
|
||
STOPPING = 3;
|
||
STOPPED = 4;
|
||
}
|
||
Lifecycle lifecycle = 1;
|
||
string error_message = 2;
|
||
|
||
// This will be a FULL update with all workspaces and agents, so clients
|
||
// should replace their current peer state. Only the Upserted fields will
|
||
// be populated.
|
||
PeerUpdate peer_update = 3;
|
||
}
|