syntax = "proto3";

import "google/protobuf/descriptor.proto";

option go_package = "/proto";

package signalexchange;

service SignalExchange {
  // Synchronously connect to the Signal Exchange service offering connection candidates and waiting for connection candidates from the other party (remote peer)
  rpc Send(EncryptedMessage) returns (EncryptedMessage) {}
  // Connect to the Signal Exchange service offering connection candidates and maintain a channel for receiving candidates from the other party (remote peer)
  rpc ConnectStream(stream EncryptedMessage) returns (stream EncryptedMessage) {}
}

// Used for sending through signal.
// The body of this message is the Body message encrypted with the Wireguard private key and the remote Peer key
message EncryptedMessage {

  // Wireguard public key
  string key = 2;

  // Wireguard public key of the remote peer to connect to
  string remoteKey = 3;

  // encrypted message Body
  bytes body = 4;
}

// A decrypted representation of the EncryptedMessage. Used locally before/after encryption
message Message {
  // WireGuard public key
  string key = 2;

  // WireGuard public key of the remote peer to connect to
  string remoteKey = 3;

  Body body = 4;
}

// Actual body of the message that can contain credentials (type OFFER/ANSWER) or connection Candidate
// This part will be encrypted
message Body {
  // Message type
  enum Type {
    OFFER = 0;
    ANSWER = 1;
    CANDIDATE = 2;
    MODE = 4;
    GO_IDLE = 5;
    HEARTBEAT = 6;
  }
  Type type = 1;
  string payload = 2;
  // wgListenPort is an actual WireGuard listen port
  uint32 wgListenPort = 3;
  string netBirdVersion = 4;
  Mode mode = 5;

  // featuresSupported list of supported features by the client of this protocol
  repeated uint32 featuresSupported = 6;

  // RosenpassConfig is a Rosenpass config of the remote peer our peer tries to connect to
  RosenpassConfig rosenpassConfig = 7;

  // relayServerAddress is url of the relay server
  optional string relayServerAddress = 8;

  reserved 9;

  optional bytes sessionId = 10;

  // relayServerIP is the IP the sender is connected to on its relay server,
  // encoded as 4 bytes (IPv4) or 16 bytes (IPv6). Receivers may use it as a
  // fallback dial target when DNS resolution of relayServerAddress fails.
  // SNI/TLS verification still uses relayServerAddress.
  optional bytes relayServerIP = 11;
}

// Mode indicates a connection mode
message Mode {
  optional bool direct = 1;
}

message RosenpassConfig {
  bytes rosenpassPubKey = 1;
  // rosenpassServerAddr is an IP:port of the rosenpass service
  string rosenpassServerAddr = 2;
}
