# Protocols

Grey Matter supports a variety of protocols. This document describes each type of connection we support and how to configure it.

* [Protocols](#protocols)
  * [Application Layer Protocols](#application-layer-protocols)
    * [HTTP](#http)
    * [HTTP/2](#http2)
    * [gRPC](#grpc)
    * [WebSockets](#websockets)
  * [Network Layer Protocols](#network-layer-protocols)
    * [TCP](#tcp)
    * [Mongo](#mongo)
    * [Redis](#redis)
    * [Kafka](#kafka)
    * [Dubbo](#dubbo)
    * [MySQL](#mysql)
    * [Zookeeper](#zookeeper)
    * [Thrift](#thrift)
  * [Encryption](#encryption)

Each protocol may be configured with TLS or mTLS [following these configurations](#encryption).

## Application Layer Protocols

### HTTP

HTTP is the default protocol used if no other protocol is set.

In order to configure HTTP, no other protocols should be configured and the `ssl_config` attribute in the service's `domain` and `cluster` objects should be omitted or set to an empty curly brace to disable SSL.

Example `cluster`:

```javascript
{
  "zone_key": "default-zone",
  "cluster_key": "exapmle-cluster",
  "name": "example",
  "instances": []
}
```

Example `domain`:

```javascript
{
  "zone_key": "default-zone",
  "domain_key": "example-domain",
  "name": "*",
  "port": 8080
}
```

This will ensure the sidecar both handles incoming connections and makes outgoing upstream connections as HTTP.

### HTTP/2

HTTP/2 is similar to HTTP, but with added performance and optimizations. It enables the usage of advanced protocols such as gRPC. For more information see [HTTP/2 specifications](https://http2.github.io/).

HTTP/2 is supported by Grey Matter via Envoy's [Protocol Selection](https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/cluster/v3/cluster.proto#enum-config-cluster-v3-cluster-clusterprotocolselection) attribute.

To configure the sidecar to use HTTP/2, the `http2_protocol_options` attribute should be set in the service's `listener` or `cluster` objects. When set in the `listener`, all incoming HTTP/2 requests to the sidecar will be handled with the configured options. When set in the `cluster`, all requests to the `cluster` from any sidecar will be handled with the configured options.

When utilizing a bi-directional stream over `HTTP/2`, we recommend setting a route timeout of `"0s"` and the option `allow_connect: true` inside the `http2_protocol_options`. This will enable the stream to stay open while not closing due to inactivity.

For information on `http2_protocol_options` settings, see [Envoy HTTP/2 Options](https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/core/v3/protocol.proto#config-core-v3-http2protocoloptions).

Example `listener`:

```javascript
{
  "zone_key": "zone-default-zone",
  "listener_key": "example-listener",
  "domain_keys": ["example-domain"],
  "name": "example",
  "ip": "0.0.0.0",
  "port": 10808,
  "protocol": "http_auto",
  "http2_protocol_options": {}
}
```

Example `cluster`:

```javascript
{
  "zone_key": "default-zone",
  "cluster_key": "example-cluster",
  "name": "example",
  "instances": [],
  "http2_protocol_options": {}
}
```

### gRPC

gRPC is an [RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) framework that uses [protocol buffers](https://github.com/protocolbuffers/protobuf) as an interface for bidirectional streaming. When using the bi-directional streaming features of gRPC, the following options need to be configured:

```javascript
{
  "zone_key": "zone-default-zone",
  "cluster_key": "example-cluster",
  "name": "example",
  "instances": [],
  "require_tls": true,
  "http2_protocol_options": {
    "allow_connect": true
  }
}
```

In this case, `allow_connect` upgrades the connection through the cluster, enabling support for a bi-directional stream. Listeners will auto detect the protocol, but if 2-way streaming is required we also recommend setting the `http2_protocol_options` with `allow_connect: true` on the listener.

Note you will also want to define a `timeout: "0s"` on your associated `route` to tell the Proxy it should hold the connection open even after remaining idle. If you do not want to hold streams open simply remove the timeout and it will default to a `15s` duration.

### WebSockets

WebSockets open a two-way interactive stream between the client and server, whereas other protocols such as HTTP are unidirectional. WebSockets can be configured for a sidecar sitting in front of a compatible backend service by enabling [WebSocket and HTTP Upgrades](https://www.envoyproxy.io/docs/envoy/v1.15.0/intro/arch_overview/http/upgrades#websocket-over-http-2-hops). To enable WebSockets, set `upgrades` to `"websocket"` in a service's proxy object. A full example is below:

```javascript
{
  "proxy_key": "gm-proxy-proxy",
  "zone_key": "default-zone",
  "name": "gm-proxy",
  "domain_keys": ["domain"],
  "listener_keys": ["listener"],
  "upgrades": "websocket",
}
```

Note that setting `upgrades` configures WebSocket connections, but will defer to the protocol of the incoming request. This allows for the sidecar to handle WebSocket connections to certain routes and clusters, and HTTP requests for others.

See [this tutorial on configuring WebSockets](https://github.com/greymatter-io/gm-control-api/blob/release-1.5/docs/examples/websockets/readme.md) for more detailed examples.

## Network Layer Protocols

Sidecars are able to field incoming and outgoing network layer protocol requests using a variety of network filters. Refer to the [network filters documentation](https://greymatter.gitbook.io/grey-matter-documentation/1.3/reference/api/fabric-api/filters/network) to learn how to configure the sidecar to use these protocols.

### TCP

To enable connecting over TCP, enable the TCP proxy filter in the service's `listener` object. [Refer to this guide for an example](https://github.com/greymatter-io/gm-control-api/tree/release-1.5/docs/examples/network_filters/tcp_proxy). Note that this cannot be configured with the Redis or Dubbo proxy filters.

### Mongo

To enable connecting to a MongoDB server, enable the Mongo proxy filter **with the TCP proxy filter** in the service's `listener` object. [Refer to this guide for an example](https://github.com/greymatter-io/gm-control-api/tree/release-1.5/docs/examples/network_filters/mongo_proxy).

### Redis

To enable connecting with to a Redis server, enable the Redis proxy filter in the service's `listener` object. [Refer to this guide for an example](https://github.com/greymatter-io/gm-control-api/tree/release-1.5/docs/examples/network_filters/redis_proxy). Note that this cannot be configured with the TCP and Dubbo proxy filters.

### Kafka

To enable connecting with to a Kafka server, enable the Kafka proxy filter in the service's `listener` object.

### Dubbo

To enable connecting to a Dubbo server, enable the Dubbo proxy filter in the service's `listener` object. Note that this cannot be configured with the TCP and Redis proxy filters.

### MySQL

To enable connecting to a MySQL server, enable the MySQL proxy filter **with the TCP proxy filter** in the service's `listener` object. [Refer to this guide for an example](https://github.com/greymatter-io/gm-control-api/tree/release-1.5/docs/examples/network_filters/mysql_proxy).

### Zookeeper

To enable connecting to a Zookeeper server, enable the Zookeeper proxy filter **with the TCP proxy filter** in the service's `listener` object. [Refer to this guide for an example](https://github.com/greymatter-io/gm-control-api/tree/release-1.5/docs/examples/network_filters/zookeeper_proxy).

### Thrift

To enable connecting with to a Thrift server, enable the Thrift proxy filter in the service's `listener` object.

## Encryption

SSL may be configured by configuring the `ssl_config` attribute in the service's `domain` and `cluster` objects.

Example cluster:

```javascript
{
  "zone_key": "default-zone",
  "cluster_key": "example-cluster",
  "name": "example",
  "instances": [],
  "ssl_config": {
      "protocols": [
        "TLSv1.2"
      ],
    "require_client_certs": true,
    "trust_file": "/etc/proxy/tls/sidecar/ca.crt",
    "cert_key_pairs": [
      {
        "certificate_path": "/etc/proxy/tls/sidecar/server.crt",
        "key_path": "/etc/proxy/tls/sidecar/server.key"
      }
    ]
  },
  "require_tls": true,
}
```

Example domain:

```javascript
{
  "zone_key": "default-zone",
  "domain_key": "example-domain",
  "name": "*",
  "port": 8080,
  "ssl_config": {
      "protocols": [
        "TLSv1.2"
      ],
    "require_client_certs": true,
    "trust_file": "/etc/proxy/tls/sidecar/ca.crt",
    "cert_key_pairs": [
      {
        "certificate_path": "/etc/proxy/tls/sidecar/server.crt",
        "key_path": "/etc/proxy/tls/sidecar/server.key"
      }
    ]
  },
  "force_https": true,
}
```

Together, the configured proxy will only handle incoming and create outgoing HTTPS requests with valid cert/key pairs using mutual [TLS version 1.2](https://tools.ietf.org/html/rfc5246). For more information on different types of HTTPS configurations, see [this doc](https://greymatter.gitbook.io/grey-matter-documentation/1.3/usage/security/tls) on configuring SSL throughout the mesh.

At this writing, Grey Matter supports the following http encryption protocols: SSLv2, SSLv3, TLSv1.1, TLSv1.2.
