syntax = "proto3";
package hbb;

message RegisterPeer {
  string id = 1;
  int32 serial = 2;
}

enum ConnType {
  DEFAULT_CONN = 0;
  FILE_TRANSFER = 1;
  PORT_FORWARD = 2;
  RDP = 3;
}

message RegisterPeerResponse { bool request_pk = 2; }

message PunchHoleRequest { 
  string id = 1; 
  NatType nat_type = 2;
  string licence_key = 3;
  ConnType conn_type = 4;
  string token = 5;
}

message PunchHole { 
  bytes socket_addr = 1;
  string relay_server = 2;
  NatType nat_type = 3;
}

message TestNatRequest {
  int32 serial = 1;
}

// per my test, uint/int has no difference in encoding, int not good for negative, use sint for negative
message TestNatResponse {
  int32 port = 1; 
  ConfigUpdate cu = 2; // for mobile
}

enum NatType {
  UNKNOWN_NAT = 0;
  ASYMMETRIC = 1;
  SYMMETRIC = 2;
}

message PunchHoleSent {
  bytes socket_addr = 1;
  string id = 2;
  string relay_server = 3;
  NatType nat_type = 4;
  string version = 5;
}

message RegisterPk {
  string id = 1;
  bytes uuid = 2;
  bytes pk = 3;
  string old_id = 4;
}

message RegisterPkResponse {
  enum Result {
    OK = 0;
    UUID_MISMATCH = 2;
    ID_EXISTS = 3;
    TOO_FREQUENT = 4;
    INVALID_ID_FORMAT = 5;
    NOT_SUPPORT = 6;
    SERVER_ERROR = 7;
  }
  Result result = 1;
}

message PunchHoleResponse {
  bytes socket_addr = 1;
  bytes pk = 2;
  enum Failure {
    ID_NOT_EXIST = 0;
    OFFLINE = 2;
    LICENSE_MISMATCH = 3;
    LICENSE_OVERUSE = 4;
  }
  Failure failure = 3;
  string relay_server = 4;
  oneof union {
    NatType nat_type = 5;
    bool is_local = 6;
  }
  string other_failure = 7;
}

message ConfigUpdate {
  int32 serial = 1;
  repeated string rendezvous_servers = 2;
}

message RequestRelay {
  string id = 1;
  string uuid = 2;
  bytes socket_addr = 3;
  string relay_server = 4;
  bool secure = 5;
  string licence_key = 6;
  ConnType conn_type = 7;
  string token = 8;
}

message RelayResponse {
  bytes socket_addr = 1;
  string uuid = 2;
  string relay_server = 3;
  oneof union {
    string id = 4;
    bytes pk = 5;
  }
  string refuse_reason = 6;
  string version = 7;
}

message SoftwareUpdate { string url = 1; }

// if in same intranet, punch hole won't work both for udp and tcp,
// even some router has below connection error if we connect itself,
//  { kind: Other, error: "could not resolve to any address" },
// so we request local address to connect.
message FetchLocalAddr { 
  bytes socket_addr = 1; 
  string relay_server = 2;
}

message LocalAddr {
  bytes socket_addr = 1;
  bytes local_addr = 2;
  string relay_server = 3;
  string id = 4;
  string version = 5;
}

message PeerDiscovery {
  string cmd = 1;
  string mac = 2;
  string id = 3;
  string username = 4;
  string hostname = 5;
  string platform = 6;
  string misc = 7;
}

message OnlineRequest {
  string id = 1;
  repeated string peers = 2;
}

message OnlineResponse {
  bytes states = 1;
}

message RendezvousMessage {
  oneof union {
    RegisterPeer register_peer = 6;
    RegisterPeerResponse register_peer_response = 7;
    PunchHoleRequest punch_hole_request = 8;
    PunchHole punch_hole = 9;
    PunchHoleSent punch_hole_sent = 10;
    PunchHoleResponse punch_hole_response = 11;
    FetchLocalAddr fetch_local_addr = 12;
    LocalAddr local_addr = 13;
    ConfigUpdate configure_update = 14;
    RegisterPk register_pk = 15;
    RegisterPkResponse register_pk_response = 16;
    SoftwareUpdate software_update = 17;
    RequestRelay request_relay = 18;
    RelayResponse relay_response = 19;
    TestNatRequest test_nat_request = 20;
    TestNatResponse test_nat_response = 21;
    PeerDiscovery peer_discovery = 22;
    OnlineRequest online_request = 23;
    OnlineResponse online_response = 24;
  }
}
