| // Copyright 2011 Google Inc. |
| // |
| // 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. |
| |
| // Specification of protocol buffers and the client-server protocol that are |
| // used by the clients of the system. |
| // |
| // Note: unless otherwise specified in a comment, all fields in all messages |
| // are required, even though they are listed as optional. |
| |
| syntax = "proto2"; |
| |
| option optimize_for = LITE_RUNTIME; |
| |
| package ipc.invalidation; |
| |
| // Here is a high-level overview of the protocol. The protocol is designed in a |
| // "message-passing" style, i.e., the client (C) or the server (S) can send any |
| // message SPONTANEOUSLY at any time and both sides have to be prepared for any |
| // message from the other side. However, even with this style, there are some |
| // "flows" which are somewhat like requests and replies. |
| |
| // 1. Initialization: When a client starts up, it needs a token to alow it to |
| // perform any other operation with the server. |
| // C -> S: InitializeMessage |
| // S -> C: TokenControlMessage |
| // |
| // 2. Registration: When a client has to register or unregister for a set of |
| // objects, the following flow occurs: |
| // C -> S: RegistrationMessage |
| // S -> C: RegistrationStatusMessage |
| // |
| // 3. Invalidation: The server sends an invalidation and the client sends back |
| // an ack. |
| // S -> C InvalidationMessage |
| // C -> S InvalidationMessage |
| // |
| // 4. Registration sync: Once in a while the server may detect that the client |
| // and server's registration state is out of sync (the server can detect this |
| // since it gets the client's registration summary in the client's message |
| // header). In that case, it asks the client some registration information |
| // and the client sends it to the server. |
| // S -> C: RegistrationSyncRequestMessage |
| // C -> S: RegistrationSyncMessage |
| // |
| // 5. Information messages: The server can occasionally for client-side |
| // information such as statistics, etc. The client responds with the |
| // requested information |
| // S -> C: InfoRequestMessage |
| // C -> S: InfoMessage |
| // |
| // ------------------------------------------------------------------------ |
| |
| // A basic message type used for versioning public proto messages and/or |
| // types. The two fields are supposed to be used as follows: |
| // |
| // * The major version number is changed whenever an incompatible protocol |
| // change or type has been made. When a message/object with a particular |
| // major version is received, the receiver needs to either know how to handle |
| // this version or it needs to drop the message |
| // |
| // * The minor version can be changed (say) to document some internal change |
| // for debugging purposes. When a message is received by a receiver, it MUST |
| // ignore the minor version number for making any protocol/type |
| // decisions. I.e., the minor version number is for debugging purposes only. |
| // |
| // Versioning is used in various places - for entities that are part of a |
| // protocol (e.g., message requests), for various client implementations, and |
| // for other data types that change independently of the protocol (e.g., |
| // session tokens). For each versioned entity, we define a specific message |
| // type to encapsulate the version of that entity (e.g., ProtocolVersion, |
| // ClientVersion, etc.). |
| message Version { |
| optional int32 major_version = 1; |
| optional int32 minor_version = 2; |
| } |
| |
| // Message included in all client <-> server messages to indicate the version |
| // of the protocol in use by the sender. |
| message ProtocolVersion { |
| optional Version version = 1; |
| } |
| |
| // Defines a specific version of the client library (for information purposes |
| // only) May not be used to make decisions at the server (use ProtocolVersion |
| // instead). |
| message ClientVersion { |
| |
| // A client-specific version number. |
| optional Version version = 1; |
| |
| // All fields below are for informational/debugging/monitoring purposes only. |
| // No critical code decision is supposed to be made using them. |
| |
| // Information about the client operating system/platform, e.g., Windows, |
| // ChromeOS. |
| optional string platform = 2; |
| |
| // Language used for the library. |
| optional string language = 3; |
| |
| // Extra information about the client (e.g., application name). |
| optional string application_info = 4; |
| } |
| |
| // Message indicating the result of an operation. |
| message StatusP { |
| |
| // Whether operation is successful or not |
| enum Code { |
| SUCCESS = 1; |
| TRANSIENT_FAILURE = 2; |
| PERMANENT_FAILURE = 3; |
| } |
| |
| optional Code code = 1; |
| |
| // Textual description of the status or additional context about any |
| // error. (Optional - Can be set for success also.) |
| optional string description = 2; |
| } |
| |
| // Identifies an object that a client can register for. |
| message ObjectIdP { |
| |
| // The source of the data. |
| optional int32 source = 1; |
| |
| // The id of the object relative to the source. Must be <= 64 bytes. |
| optional bytes name = 2; |
| } |
| |
| // A message containing the part of the client's id that the application |
| // controls. This id is used for squelching invalidations on the server side. |
| // For example, if a client C1 modifies object x and informs the backend about |
| // C1's application client id as part of the invalidation. The backend can then |
| // avoid sending the invalidation unnecessarily to that client. |
| // |
| // If the application wishes to use this squelching feature, it must assign a |
| // globally unique client_name for a given client_type so that the particular |
| // instantation of the application can be identified. |
| message ApplicationClientIdP { |
| // The type of the client. |
| optional int32 client_type = 1; |
| |
| // A client name or unique id assigned by the application. Application should |
| // choose a unique name for different client instances if it wants to squelch |
| // invalidations by name (as discussed above). |
| optional bytes client_name = 2; |
| } |
| |
| // Invalidation for a given object/version. |
| message InvalidationP { |
| // The id of the object being invalidated. |
| optional ObjectIdP object_id = 1; |
| |
| // Whether the invalidation is for a known version of the object as assigned |
| // by an application backend (is_known_version == true) or an unknown system |
| // version synthesized by the invalidation service. (Note that if |
| // is_known_version is false then is_trickle_restart be true or missing |
| // because an unknown version implies that invalidation versions prior to the |
| // current backend version may have been dropped.) |
| optional bool is_known_version = 2; |
| |
| // Version being invalidated (see comment on is_known_version). If the |
| // is_known_version is false, the version corresponds to an internal "system |
| // version" for *that* object. An object's system version has no meaning to |
| // the application other than the fact that these system versions are also |
| // monotonically increasing and the client must ack such an invalidation with |
| // this system version (and an ack for a later system version acknowledges an |
| // invalidation for all earlier system version for *that* object. |
| optional int64 version = 3; |
| |
| // Whether the object's Trickle is restarting at this version. |
| // sets this value to true to inform Trickle API clients that it may |
| // have dropped invalidations prior to "version", or, if is_known_version is |
| // false, prior to the current backend version. |
| optional bool is_trickle_restart = 6 [default = false]; |
| |
| // Optional payload associated with this invalidation. |
| optional bytes payload = 4; |
| |
| // DEPRECATED: bridge arrival time is now maintained by |
| // InvalidationMetadataP in the SourcedInvalidation, InvalidationContents and |
| // ClientInvalidation containers. |
| optional int64 bridge_arrival_time_ms_deprecated = 5 [deprecated=true]; |
| } |
| |
| // Specifies the intention to change a registration on a specific object. To |
| // update registrations, a client sends a message containing repeated |
| // RegistrationP messages. |
| message RegistrationP { |
| enum OpType { |
| REGISTER = 1; |
| UNREGISTER = 2; |
| } |
| |
| // The object for which to (un)register. |
| optional ObjectIdP object_id = 1; |
| |
| // Whether to register or unregister. |
| optional OpType op_type = 2; |
| } |
| |
| // Summary of the registration state associated with a particular client, sent |
| // in the header of client<->server messages. This summary has two different |
| // (but related) meanings depending on where it is used: |
| // |
| // 1) In a client->server message, it describes the DESIRED client state. |
| // 2) In a server->client message, it describes the ACTUAL state at the server |
| // for that client. |
| message RegistrationSummary { |
| // Number of registrations desired (client) or held (server). |
| optional int32 num_registrations = 1; |
| |
| // Top-level digest over the registrations. |
| // |
| // The digest for an object id is computed as following (the digest chosen for |
| // this method is SHA-1): |
| // |
| // digest = new Digest(); |
| // digest.update(Little endian encoding of object source type) |
| // digest.update(object name) |
| // digest.getDigestSummary() |
| // |
| // For a set of objects, digest is computing by sorting lexicographically |
| // based on their digests and then performing the update process given above |
| // (i.e., calling digest.update on each object's digest and then calling |
| // getDigestSummary at the end). |
| optional bytes registration_digest = 2; |
| } |
| |
| // Header included on every client -> server message. |
| message ClientHeader { |
| |
| // Protocol version of this message. |
| optional ProtocolVersion protocol_version = 1; |
| |
| // Token identifying the client. Tokens are issued by the server in response |
| // to client requests (see InitializeMessage, below). In order to perform any |
| // operation other than initialization, the client must supply a token. When |
| // performing initialization, this field must be left unset. |
| optional bytes client_token = 2; |
| |
| // Optional summary of the client's desired registration state. The client is |
| // encouraged to provide this summary in every message once a "steady" state |
| // of registrations/unregistrations has been reached. For example, it may not |
| // want to send this summary during initialization (but after the initial set |
| // has been registered, it should try to send it). |
| optional RegistrationSummary registration_summary = 3; |
| |
| // Timestamp from the client's clock, expressed as ms since 00:00:00 UTC, 1 |
| // January 1970 (i.e., the UNIX epoch) - for debugging/monitoring purposes. |
| optional int64 client_time_ms = 4; |
| |
| // Highest server timestamp observed by the client (the server includes its |
| // time on every message to the client). Note: this time is NOT necessarily |
| // expressed as relative to the UNIX epoch - for debugging/monitoring |
| // purposes. |
| optional int64 max_known_server_time_ms = 5; |
| |
| // Message id to identify the message -for debugging/monitoring purposes. |
| optional string message_id = 6; |
| |
| // Client typecode (as in the InitializeMessage, below). This field may or |
| // may not be set. |
| optional int32 client_type = 7; |
| } |
| |
| // A message from the client to the server. |
| message ClientToServerMessage { |
| // Header. |
| optional ClientHeader header = 1; |
| |
| // Any or all of the follow messages may be present. |
| |
| // Optional initialization message, used to obtain a new token. Note that, if |
| // present, this message is always processed before the messages below, and |
| // those messages will be interpreted relative to the new token assigned here. |
| optional InitializeMessage initialize_message = 2; |
| |
| // Optional request to perform registrations. |
| optional RegistrationMessage registration_message = 3; |
| |
| // Optional data for registration sync. |
| optional RegistrationSyncMessage registration_sync_message = 4; |
| |
| // Optional invalidation acks. |
| optional InvalidationMessage invalidation_ack_message = 5; |
| |
| // Optional information about the client. |
| optional InfoMessage info_message = 6; |
| } |
| |
| // Used to obtain a new token when the client does not have one. |
| message InitializeMessage { |
| |
| // Defines how clients serialize object ids when computing digests for |
| // registrations. |
| enum DigestSerializationType { |
| |
| // The digest for an object id is computed by serializing the object id into |
| // bytes. |
| BYTE_BASED = 1; |
| |
| // The digest for an object id is computed by serializing the object id into |
| // an array of numbers. |
| NUMBER_BASED = 2; |
| } |
| |
| // Type of the client. This value is assigned by the backend notification |
| // system (out-of-band) and the client must use the correct value. |
| optional int32 client_type = 1; |
| |
| // Nonce. This value will be echoed as the existing token in the header of |
| // the server message that supplies the new token (the new token itself will |
| // be provided in a TokenControlMessage; see below). |
| optional bytes nonce = 2; |
| |
| // Id of the client as assigned by the application. |
| optional ApplicationClientIdP application_client_id = 3; |
| |
| // Type of registration digest used by this client. |
| optional DigestSerializationType digest_serialization_type = 4; |
| } |
| |
| // Registration operations to perform. |
| message RegistrationMessage { |
| repeated RegistrationP registration = 1; |
| } |
| |
| // Message from the client to the server. |
| message RegistrationSyncMessage { |
| |
| // Objects for which the client is registered. |
| repeated RegistrationSubtree subtree = 1; |
| } |
| |
| // Message sent from the client to the server about registered objects |
| // (typically) in response to a registration sync request. |
| // |
| // The name of the message implies a "tree" for future expansion where the |
| // intention is to not necessarily send the complete set of objects but to |
| // partition the object space into multiple ranges and then exchange Merkle-tree |
| // like data structures to determine which ranges are out-of-sync. |
| message RegistrationSubtree { |
| // Registered objects |
| repeated ObjectIdP registered_object = 1; |
| } |
| |
| // A message from the client to the server with info such as performance |
| // counters, client os info, etc. |
| message InfoMessage { |
| optional ClientVersion client_version = 1; |
| |
| // Config parameters used by the client. |
| // Deprecated and removed - the client_config parameter is what is used now. |
| repeated PropertyRecord config_parameter = 2; |
| |
| // Performance counters from the client. |
| repeated PropertyRecord performance_counter = 3; |
| |
| // If 'true', indicates that the client does not know the server's |
| // registration summary, so the server should respond with it even if the |
| // client's summary matches the server's. |
| optional bool server_registration_summary_requested = 4; |
| |
| // Configuration parameters for this client. |
| optional ClientConfigP client_config = 5; |
| } |
| |
| // Information about a single config/performance counter value in the |
| // InfoMessage. |
| message PropertyRecord { |
| |
| // Name of the performance counter/config parameter. |
| optional string name = 1; |
| |
| // Value of the performance counter/config parameter. |
| optional int32 value = 2; |
| } |
| |
| message ServerHeader { |
| // Protocol version of this message. |
| optional ProtocolVersion protocol_version = 1; |
| |
| // Current token that the server expects the client to have. Clients must |
| // ignore messages where this token field does not match their current token. |
| // During initialization, the client's "token" is the nonce that it generates |
| // and sends in the InitializeMessage. |
| optional bytes client_token = 2; |
| |
| // Summary of registration state held by the server for the client. |
| optional RegistrationSummary registration_summary = 3; |
| |
| // Timestamp from the server's clock. No guarantee on when this time is |
| // relative to. |
| optional int64 server_time_ms = 4; |
| |
| // Message id to identify the message (for debug purposes only). |
| optional string message_id = 5; |
| } |
| |
| message ServerToClientMessage { |
| optional ServerHeader header = 1; |
| |
| // Message to assign a new client token or invalidate an existing one. Note |
| // that, if present, this message is always processed before the messages |
| // below, and those messages will be interpreted relative to the new token |
| // assigned here. |
| optional TokenControlMessage token_control_message = 2; |
| |
| // Invalidations. |
| optional InvalidationMessage invalidation_message = 3; |
| |
| // Registration operation replies. |
| optional RegistrationStatusMessage registration_status_message = 4; |
| |
| // Request for client registration state. |
| optional RegistrationSyncRequestMessage registration_sync_request_message = 5; |
| |
| // Request to change config from the server. |
| optional ConfigChangeMessage config_change_message = 6; |
| |
| // Request for client information. |
| optional InfoRequestMessage info_request_message = 7; |
| |
| // Asynchronous error information that the server sends to the client. |
| optional ErrorMessage error_message = 8; |
| } |
| |
| // Message used to supply a new client token or invalidate an existing one. |
| message TokenControlMessage { |
| // If status is failure, new_token cannot be set. |
| optional bytes new_token = 1; // If missing, means destroy_token |
| } |
| |
| // Status of a particular registration (could be sent spontaneously by the |
| // server or in response to a registration request). |
| message RegistrationStatus { |
| optional RegistrationP registration = 1; |
| optional StatusP status = 2; |
| } |
| |
| // Registration status of several messages from the server to the client. |
| message RegistrationStatusMessage { |
| repeated RegistrationStatus registration_status = 1; |
| } |
| |
| // Request from the server to get the registration info from the client for |
| // sync purposes. |
| message RegistrationSyncRequestMessage { |
| } |
| |
| // A set of invalidations from the client to the server or vice-versa |
| message InvalidationMessage { |
| repeated InvalidationP invalidation = 1; |
| } |
| |
| // A request from the server to the client for information such as |
| // performance counters, client os, etc |
| message InfoRequestMessage { |
| enum InfoType { |
| GET_PERFORMANCE_COUNTERS = 1; |
| } |
| repeated InfoType info_type = 1; |
| } |
| |
| // A rate limit: a count of events and a window duration in which the events |
| // may occur. |
| message RateLimitP { |
| |
| // The size of the window over which the rate limit applies. |
| optional int32 window_ms = 1; |
| |
| // The number of events allowed within a given window. |
| optional int32 count = 2; |
| } |
| |
| // Configuration parameters for the protocol handler in the Ticl. |
| message ProtocolHandlerConfigP { |
| // Batching delay - certain messages (e.g., registrations, invalidation acks) |
| // are sent to the server after this delay. |
| optional int32 batching_delay_ms = 1 [default = 500]; |
| |
| // Rate limits for sending messages. Only two levels allowed currently. |
| repeated RateLimitP rate_limit = 2; |
| } |
| |
| // Configuration parameters for the Ticl. |
| message ClientConfigP { |
| |
| optional Version version = 1; |
| |
| // The delay after which a network message sent to the server is considered |
| // timed out. |
| optional int32 network_timeout_delay_ms = 2 [default = 60000]; |
| |
| // Retry delay for a persistent write if it fails |
| optional int32 write_retry_delay_ms = 3 [default = 10000]; |
| |
| // Delay for sending heartbeats to the server. |
| optional int32 heartbeat_interval_ms = 4 [default = 1200000]; |
| |
| // Delay after which performance counters are sent to the server. |
| optional int32 perf_counter_delay_ms = 5 [default = 21600000]; // 6 hours. |
| |
| // The maximum exponential backoff factor used for network and persistence |
| /// timeouts. |
| optional int32 max_exponential_backoff_factor = 6 [default = 500]; |
| |
| // Smearing percent for randomizing delays. |
| optional int32 smear_percent = 7 [default = 20]; |
| |
| // Whether the client is transient, that is, does not write its session |
| // token to durable storage. |
| // TODO(xiaolan): (BUG 5627144) need to expose to the clients. |
| // For android the default is false. But for mtrx the default is true. |
| optional bool is_transient = 8 [default = false]; |
| |
| // Initial delay for a heartbeat after restarting from persistent state. We |
| // use this so that the application has a chance to respond to the |
| // reissueRegistrations call. |
| optional int32 initial_persistent_heartbeat_delay_ms = 9 [default = 2000]; |
| |
| // Configuration for the protocol client to control batching etc. |
| optional ProtocolHandlerConfigP protocol_handler_config = 10; |
| |
| // Whether the channel supports delivery while the client is offline. If |
| // true, then the servers' use of the channel is such that the |
| // following holds: if any number of messages are sent to the client while |
| // the client is unreachable, then the channel will eventually deliver at |
| // least one message to the client such that, on receiving the message, the |
| // client will send a message to the server. E.g., the channel could deliver |
| // a single invalidation or a single registration sync request. C2DM is |
| // an example of a suitable channel. |
| // |
| // When this is true, the Ticl will record in persistent storage the last |
| // time it sent a message to the server. On persistent restart, it will not |
| // send a message to the server unless the last one was sent more than a |
| // heartbeat-interval ago. This is designed to support efficient Android |
| // clients, which will destroy and recreate the Ticl when transitioning |
| // between foreground and background states. |
| optional bool channel_supports_offline_delivery = 11 [default = false]; |
| |
| // If the client loses network connectivity, it will send a heartbeat after it |
| // comes online, unless it had already sent a message more recently than this |
| // threshold. |
| optional int32 offline_heartbeat_threshold_ms = 12 [default = 60000]; |
| |
| // Whether the client allows suppression. If true (the default), then |
| // both continuous and restarted invalidations result in an invalidate() |
| // upcall, which is appropriate for invalidation clients. If false, |
| // then restarted invalidations result in an invalidateUnknownVersion() |
| // upcall, which provides correct semantics for Trickles clients. |
| optional bool allow_suppression = 13 [default = true]; |
| } |
| |
| // A message asking the client to change its configuration parameters |
| message ConfigChangeMessage { |
| |
| // On receipt of this value, do not send any new message to the server |
| // for the specified delay (this message needs to be accepted without |
| // any token check). A zero value is ignored by the client. So the lowest |
| // value for this field is 1. This concept exists to allow the server |
| // to tell the clients that they should not come back to the server |
| // for some period of time. |
| optional int64 next_message_delay_ms = 1; |
| } |
| |
| // An error message that contains an enum for different types of failures with a |
| // textual description of the failure (as the need arises new error codes will |
| // be added to this message). |
| message ErrorMessage { |
| |
| enum Code { |
| AUTH_FAILURE = 1; // Authorization or authentication failure. |
| UNKNOWN_FAILURE = 10000; // Some failure which is not described above. |
| }; |
| |
| optional Code code = 1; |
| |
| // Textual description of the error |
| optional string description = 2; |
| } |