syntax = "proto3";
package defguard.gateway.v2;

import "enterprise/v2/firewall/firewall.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "v2/common.proto";

/*
 * Networking and VPN configuration send from Core to Gateway.
 */
message Configuration {
  string name = 1;
  string private_key = 2;
  uint32 port = 3;
  repeated Peer peers = 4;
  repeated string addresses = 5;
  optional defguard.enterprise.firewall.v2.FirewallConfig firewall_config = 6;
  uint32 mtu = 7;
  uint32 fwmark = 8;
}

enum UpdateType {
  UPDATE_TYPE_UNSPECIFIED = 0;
  UPDATE_TYPE_CREATE = 1;
  UPDATE_TYPE_MODIFY = 2;
  UPDATE_TYPE_DELETE = 3;
}

message Peer {
  string pubkey = 1;
  repeated string allowed_ips = 2;
  optional string preshared_key = 3;
  optional uint32 keepalive_interval = 4;
}

message Update {
  UpdateType update_type = 1;
  oneof update {
    Peer peer = 2;
    Configuration network = 3;
    defguard.enterprise.firewall.v2.FirewallConfig firewall_config = 4;
    google.protobuf.Empty disable_firewall = 5;
  }
}

message PeerStats {
  string public_key = 1;
  string endpoint = 2;
  uint64 upload = 3;
  uint64 download = 4;
  uint32 keepalive_interval = 5;
  optional google.protobuf.Timestamp latest_handshake = 6;
  string allowed_ips = 7;
}

/*
 * CoreResponse represents messages send from Core to Gateway
 * in response to CoreRequest.
 */
message CoreResponse {
  uint64 id = 1;
  oneof payload {
    // Allow empty messages to keep the connection alive.
    google.protobuf.Empty empty = 2;
    Configuration config = 3;
    Update update = 4;
  }
}

/*
 * CoreRequest represents messages send from Gateway to Core.
 */
message CoreRequest {
  uint64 id = 1;
  oneof payload {
    PeerStats peer_stats = 2;
    google.protobuf.Empty config_request = 3;
  }
}

service Gateway {
  /*
   * Bi-directional communication between Core and Gateway.
   * For security reasons, the connection has to be initiated by Core,
   * so requests and responses are actually sent in reverse.
   */
  rpc Bidi(stream CoreResponse) returns (stream CoreRequest);
  /*
   * Purges existing on-disk gRPC TLS credentials and signals the server
   * to re-enter setup mode so that core can provision new ones.
   */
  rpc Purge(google.protobuf.Empty) returns (google.protobuf.Empty);
}

// Service used for initial Gateway setup, for configuring TLS certificate
// on Gateway for gRPC communication.
service GatewaySetup {
  rpc Start(google.protobuf.Empty) returns (stream defguard.common.v2.LogEntry);
  rpc GetCsr(defguard.common.v2.CertificateInfo) returns (defguard.common.v2.DerPayload);
  rpc SendCert(defguard.common.v2.CertBundle) returns (google.protobuf.Empty);
}
