syntax = "proto3"; option go_package = "github.com/coder/coder/v2/tailnet/proto"; package coder.tailnet.v2; import "google/protobuf/timestamp.proto"; // Importing for time.Time import "google/protobuf/duration.proto"; // Importing for time.Duration import "google/protobuf/wrappers.proto"; // Importing for nullable types message DERPMap { message HomeParams { map region_score = 1; } HomeParams home_params = 1; message Region { int64 region_id = 1; bool embedded_relay = 2; string region_code = 3; string region_name = 4; bool avoid = 5; message Node { string name = 1; int64 region_id = 2; string host_name = 3; string cert_name = 4; string ipv4 = 5; string ipv6 = 6; int32 stun_port = 7; bool stun_only = 8; int32 derp_port = 9; bool insecure_for_tests = 10; bool force_http = 11; string stun_test_ip = 12; bool can_port_80 = 13; } repeated Node nodes = 6; } map regions = 2; } message StreamDERPMapsRequest {} // defined in tailnet/coordinator.go message Node { int64 id = 1; google.protobuf.Timestamp as_of = 2; bytes key = 3; string disco = 4; int32 preferred_derp = 5; map derp_latency = 6; map derp_forced_websocket = 7; repeated string addresses = 8; repeated string allowed_ips = 9; repeated string endpoints = 10; } message CoordinateRequest { message UpdateSelf { Node node = 1; } UpdateSelf update_self = 1; message Disconnect {} Disconnect disconnect = 2; message Tunnel { bytes id = 1; } Tunnel add_tunnel = 3; Tunnel remove_tunnel = 4; // ReadyForHandskales are sent from destinations back to the source, // acknowledging receipt of the source's node. If the source starts pinging // before a ReadyForHandshake, the Wireguard handshake will likely be // dropped. message ReadyForHandshake { bytes id = 1; } repeated ReadyForHandshake ready_for_handshake = 5; } message CoordinateResponse { message PeerUpdate { bytes id = 1; Node node = 2; enum Kind { KIND_UNSPECIFIED = 0; NODE = 1; DISCONNECTED = 2; LOST = 3; READY_FOR_HANDSHAKE = 4; } Kind kind = 3; string reason = 4; } repeated PeerUpdate peer_updates = 1; string error = 2; } message IPFields { int32 version = 1; enum IPClass { PUBLIC = 0; PRIVATE = 1; LINK_LOCAL = 2; LOOPBACK = 3; } IPClass class = 2; } message Netcheck { bool UDP = 1; bool IPv6 = 2; bool IPv4 = 3; bool IPv6CanSend = 4; bool IPv4CanSend = 5; bool ICMPv4 = 6; google.protobuf.BoolValue OSHasIPv6 = 7; google.protobuf.BoolValue MappingVariesByDestIP = 8; google.protobuf.BoolValue HairPinning = 9; google.protobuf.BoolValue UPnP = 10; google.protobuf.BoolValue PMP = 11; google.protobuf.BoolValue PCP = 12; int64 PreferredDERP = 13; // 0 for unknown map RegionV4Latency = 14; map RegionV6Latency = 15; message NetcheckIP { string hash = 1; IPFields fields = 2; } NetcheckIP GlobalV4 = 17; NetcheckIP GlobalV6 = 18; } message TelemetryEvent { enum Status { CONNECTED = 0; DISCONNECTED = 1; } enum ClientType { CLI = 0; AGENT = 1; CODERD = 2; WSPROXY = 3; } message P2PEndpoint { string hash = 1; int32 port = 2; IPFields fields = 3; } bytes id = 1; google.protobuf.Timestamp time = 2; string application = 3; Status status = 4; string disconnection_reason = 5; ClientType client_type = 6; string client_version = 19; uint64 node_id_self = 7; uint64 node_id_remote = 8; P2PEndpoint p2p_endpoint = 9; int32 home_derp = 10; DERPMap derp_map = 11; Netcheck latest_netcheck = 12; google.protobuf.Duration connection_age = 13; google.protobuf.Duration connection_setup = 14; google.protobuf.Duration p2p_setup = 15; google.protobuf.Duration derp_latency = 16; google.protobuf.Duration p2p_latency = 17; google.protobuf.FloatValue throughput_mbits = 18; } message TelemetryRequest { repeated TelemetryEvent events = 1; } message TelemetryResponse {} service Tailnet { rpc PostTelemetry(TelemetryRequest) returns (TelemetryResponse); rpc StreamDERPMaps(StreamDERPMapsRequest) returns (stream DERPMap); rpc Coordinate(stream CoordinateRequest) returns (stream CoordinateResponse); }