# Request

> The payload of the channel request the server sends: the connection as JSON, with no tag.

Canonical: https://protocol.diverge.network/2.3.0/endpoints/daemons-accept/server/connection/request/
Specification revision: 2.3.0

```text
[connection JSON …]
```

- **No tag.** The server opens one kind of channel on an accept
  scope, so its channel request carries no tag: the payload is the
  connection as JSON, read as [Notation](/2.3.0/endpoints/#notation)
  provides.
- **`connection_id`.** The id the server minted for the connection,
  an integer. The acceptor quotes it, as four bytes big-endian, in
  the channel request of its half.
- **`identity`.** The identity of the connection the connect scope
  was opened on, as the [authorization](/2.3.0/authorization/) established
  it.
- **`address`.** The peer IP address of that connection, as the
  server observed it.
- **`mode`.** The connector's mode, verbatim: one object whose one
  member names the mode, `unbrokered`, whose value carries the
  credential the connector presents to the acceptor.

The channel request is defined by `diverge-sdk-rs/src/provider/endpoints/daemons/accept/server/channel_request/frame.rs`:

```rust
//! What a server's channel request frame carries on an accept scope.

use crate::shared::daemons::Connection;
use crate::wire::decode::Decode;
use crate::wire::encode::{Encode, Writer};

/// A connector arrived: the provider's half of its connection.
///
/// What arrives on the channel is the daemon's answer — its server
/// frames, one per channel response — and the daemon finishing the
/// channel is the daemon hanging up; a finish with nothing before it
/// is the daemon declining. The daemon's own half is a channel it
/// opens, quoting the id this carries.
///
/// # A struct, and no tag
///
/// One thing to ask is a struct; an enum of one variant would be a
/// discriminant with nothing to discriminate — and a tag byte is that
/// discriminant written on the wire, so it goes for the same reason.
/// The payload is the [`Connection`] as JSON.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Frame(
    /// Who, from where, under which id, and how they say they are let
    /// in.
    pub Connection,
);

impl Encode for Frame {
    /// The ordinary JSON failure.
    type Error = serde_json::Error;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        serde_json::to_writer(out, &self.0)
    }
}

impl Decode<'_> for Frame {
    /// The ordinary JSON failure.
    type Error = serde_json::Error;

    fn decode(bytes: &[u8]) -> Result<Self, Self::Error> {
        serde_json::from_slice(bytes).map(Frame)
    }
}
```

and by `diverge-sdk-rs/src/shared/daemons/connection.rs`:

```rust
//! One daemon connection, as the provider tells the acceptor of it.

use std::net::IpAddr;

use serde::{Deserialize, Serialize};

use super::Mode;

/// A connector arriving: what the provider says of it when it opens
/// the acceptor's half of the connection. The id correlates the two
/// channels the connection is, as a container program's daemon
/// connection is correlated; the identity and the address are the
/// provider's own word — the identity it authorized the connector's
/// connection under, the peer address it saw that connection come
/// from — and the mode is what the connector asserted, relayed
/// unread, for the acceptor to judge.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Connection {
    /// The connection, by the id the provider minted: what the
    /// acceptor quotes when it opens its own half.
    pub connection_id: u32,
    /// The identity the provider authorized the connector under.
    pub identity: String,
    /// Where the connector's connection to the provider came from, as
    /// the provider saw it. What an account's address, if it names
    /// one, is compared with.
    pub address: IpAddr,
    /// How the connector authenticates to the acceptor: see [`Mode`].
    pub mode: Mode,
}
```

and by `diverge-sdk-rs/src/shared/daemons/mode.rs`:

```rust
//! How a connecting daemon authenticates to the daemon it connects
//! to.

use serde::{Deserialize, Serialize};

/// The connector's way in: what it would present as the first frame
/// of a daemon connection, carried here instead, since a connection
/// relayed through a provider has no `Auth` frame of its own. One
/// object whose one member is the mode, by name:
/// `{"unbrokered":{"credential":…}}`. One mode today; a brokered mode
/// is a second member when the wire defines it, and nothing moves.
/// The provider relays it to the acceptor unread, and the acceptor
/// judges it as it judges a credential presented on a socket.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Mode {
    /// The two daemons already know each other: the connector
    /// presents a credential of an account it holds on the acceptor.
    Unbrokered {
        /// The credential, as the connector would present it in an
        /// `Auth::Unbrokered`: the key the acceptor minted for the
        /// account, byte for byte.
        credential: String,
    },
}
```
