// Copyright 2020 Anapaya Systems
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package proto.daemon.v1;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "proto/drkey/v1/drkey.proto";

option go_package = "github.com/scionproto/scion/pkg/proto/daemon";

service DaemonService {
  // Return a set of paths to the requested destination.
  rpc Paths(PathsRequest) returns (PathsResponse) {}
  // Return information about an AS.
  rpc AS(ASRequest) returns (ASResponse) {}
  // Return the underlay addresses associated with
  // the specified interfaces.
  rpc Interfaces(InterfacesRequest) returns (InterfacesResponse) {}
  // Return the underlay addresses associated with the
  // specified services.
  rpc Services(ServicesRequest) returns (ServicesResponse) {}
  // Inform the SCION Daemon of a revocation.
  rpc NotifyInterfaceDown(NotifyInterfaceDownRequest) returns (NotifyInterfaceDownResponse) {}
  // DRKeyASHost returns a key that matches the request.
  rpc DRKeyASHost(DRKeyASHostRequest) returns (DRKeyASHostResponse) {}
  // DRKeyHostAS returns a key that matches the request.
  rpc DRKeyHostAS(DRKeyHostASRequest) returns (DRKeyHostASResponse) {}
  // DRKeyHostHost returns a key that matches the request.
  rpc DRKeyHostHost(DRKeyHostHostRequest) returns (DRKeyHostHostResponse) {}
}

message PathsRequest {
  // ISD-AS of the source of the path request.
  uint64 source_isd_as = 1;
  // ISD-AS of the destination of the path request.
  uint64 destination_isd_as = 2;
  // Choose to fetch fresh paths for this request instead
  // of having the server reply from its cache.
  bool refresh = 3;
  // Request hidden paths instead of standard paths.
  bool hidden = 4;
}

message PathsResponse {
  // List of paths found by the daemon.
  repeated Path paths = 1;
}

message Path {
  // The raw data-plane path.
  bytes raw = 1;
  // Interface for exiting the local AS using this path.
  Interface interface = 2;
  // The list of interfaces the path is composed of.
  repeated PathInterface interfaces = 3;
  // The maximum transmission unit (MTU) on the path.
  uint32 mtu = 4;
  // The point in time when this path expires. In seconds since UNIX epoch.
  google.protobuf.Timestamp expiration = 5;
  // Latency lists the latencies between any two consecutive interfaces.
  // Entry i describes the latency between interface i and i+1.
  // Consequently, there are N-1 entries for N interfaces.
  // A negative value indicates that the AS did not announce a latency for
  // this hop.
  repeated google.protobuf.Duration latency = 6;
  // Bandwidth lists the bandwidth between any two consecutive interfaces, in
  // Kbit/s.
  // Entry i describes the bandwidth between interfaces i and i+1.
  // A 0-value indicates that the AS did not announce a bandwidth for this
  // hop.
  repeated uint64 bandwidth = 7;
  // Geo lists the geographical position of the border routers along the
  // path.
  // Entry i describes the position of the router for interface i.
  // A 0-value indicates that the AS did not announce a position for this
  // router.
  repeated GeoCoordinates geo = 8;
  // LinkType contains the announced link type of inter-domain links.
  // Entry i describes the link between interfaces 2*i and 2*i+1.
  repeated LinkType link_type = 9;
  // InternalHops lists the number of AS internal hops for the ASes on path.
  // Entry i describes the hop between interfaces 2*i+1 and 2*i+2 in the same
  // AS.
  // Consequently, there are no entries for the first and last ASes, as these
  // are not traversed completely by the path.
  repeated uint32 internal_hops = 10;
  // Notes contains the notes added by ASes on the path, in the order of
  // occurrence.
  // Entry i is the note of AS i on the path.
  repeated string notes = 11;
  // EpicAuths contains the EPIC authenticators used to calculate the PHVF and LHVF.
  EpicAuths epic_auths = 12;
}

message EpicAuths {
  // AuthPHVF is the authenticator use to calculate the PHVF.
  bytes auth_phvf = 1;
  // AuthLHVF is the authenticator use to calculate the LHVF.
  bytes auth_lhvf = 2;
}

message PathInterface {
  // ISD-AS the interface belongs to.
  uint64 isd_as = 1;
  // ID of the interface in the AS.
  uint64 id = 2;
}

message GeoCoordinates {
  // Latitude of the geographic coordinate, in the WGS 84 datum.
  float latitude = 1;
  // Longitude of the geographic coordinate, in the WGS 84 datum.
  float longitude = 2;
  // Civic address of the location.
  string address = 3;
}

enum LinkType {
  // Unspecified link type.
  LINK_TYPE_UNSPECIFIED = 0;
  // Direct physical connection.
  LINK_TYPE_DIRECT = 1;
  // Connection with local routing/switching.
  LINK_TYPE_MULTI_HOP = 2;
  // Connection overlaid over publicly routed Internet.
  LINK_TYPE_OPEN_NET = 3;
}

message ASRequest {
  // ISD-AS of the AS information is requested about. The 0 value
  // can be used to discover the ISD-AS number of the local AS.
  uint64 isd_as = 1;
}

message ASResponse {
  // ISD-AS of the AS information was requested about.
  uint64 isd_as = 1;
  // Indicates whether the local AS is core.
  bool core = 2;
  // The maximum transmission unit (MTU) in the local AS.
  uint32 mtu = 3;
}

message InterfacesRequest {}

message InterfacesResponse {
  // Map from SCION interface IDs in the local AS to interface details.
  map<uint64, Interface> interfaces = 1;
}

message Interface {
  // Underlay address to exit through the interface.
  Underlay address = 1;
}

message ServicesRequest {}

message ServicesResponse {
  // Map from service names to known services.
  map<string, ListService> services = 1;
}

message ListService {
  // Services is the list of services.
  repeated Service services = 1;
}

message Service {
  // Address of the service instance, in RFC 3986 format.
  string uri = 1;
}

// Address of an underlay socket.
message Underlay {
  // The underlay address in standard IP:port notation (e.g., 192.0.2.1:10000
  // or [2001:db8::1]:10000). The underlay is UDP/IP.
  string address = 1;
}

message NotifyInterfaceDownRequest {
  // ISD-AS the failing interface belongs to.
  uint64 isd_as = 1;
  // ID of the failing interface.
  uint64 id = 2;
}

message NotifyInterfaceDownResponse {}

message DRKeyHostASRequest {
  // Point in time where requested key is valid.
  google.protobuf.Timestamp val_time = 1;
  // Protocol value.
  proto.drkey.v1.Protocol protocol_id = 2;
  // Src ISD-AS of the requested DRKey.
  uint64 src_ia = 3;
  // Dst ISD-AS of the requested DRKey.
  uint64 dst_ia = 4;
  // Src Host of the request DRKey.
  string src_host = 5;
}

message DRKeyHostASResponse {
  // Begin of validity period of DRKey.
  google.protobuf.Timestamp epoch_begin = 1;
  // End of validity period of DRKey.
  google.protobuf.Timestamp epoch_end = 2;
  // Level2 key.
  bytes key = 3;
}

message DRKeyASHostRequest {
  // Point in time where requested key is valid.
  google.protobuf.Timestamp val_time = 1;
  // Protocol value.
  proto.drkey.v1.Protocol protocol_id = 2;
  // Src ISD-AS of the requested DRKey.
  uint64 src_ia = 3;
  // Dst ISD-AS of the requested DRKey.
  uint64 dst_ia = 4;
  // Dst Host of the request DRKey.
  string dst_host = 5;
}

message DRKeyASHostResponse {
  // Begin of validity period of DRKey.
  google.protobuf.Timestamp epoch_begin = 1;
  // End of validity period of DRKey.
  google.protobuf.Timestamp epoch_end = 2;
  // Level2 key.
  bytes key = 3;
}

message DRKeyHostHostRequest {
  // Point in time where requested key is valid.
  google.protobuf.Timestamp val_time = 1;
  // Protocol value.
  proto.drkey.v1.Protocol protocol_id = 2;
  // Src ISD-AS of the requested DRKey.
  uint64 src_ia = 3;
  // Dst ISD-AS of the requested DRKey.
  uint64 dst_ia = 4;
  // Src Host of the request DRKey.
  string src_host = 5;
  // Dst Host of the request DRKey.
  string dst_host = 6;
}

message DRKeyHostHostResponse {
  // Begin of validity period of DRKey.
  google.protobuf.Timestamp epoch_begin = 1;
  // End of validity period of DRKey.
  google.protobuf.Timestamp epoch_end = 2;
  // Level2 key.
  bytes key = 3;
}
