mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-06-19 17:36:35 +00:00

## Summary In order to make cloudflared behavior more predictable and prevent an exhaustion of resources, we have decided to add session limits that can be configured by the user. This commit adds the session limiter to the HTTP/TCP handling path. For now the limiter is set to run only in unlimited mode.
117 lines
2.8 KiB
Go
117 lines
2.8 KiB
Go
package pogs
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
capnp "zombiezen.com/go/capnproto2"
|
|
"zombiezen.com/go/capnproto2/pogs"
|
|
|
|
"github.com/cloudflare/cloudflared/tunnelrpc/proto"
|
|
)
|
|
|
|
// ConnectionType indicates the type of underlying connection proxied within the QUIC stream.
|
|
type ConnectionType uint16
|
|
|
|
const (
|
|
ConnectionTypeHTTP ConnectionType = iota
|
|
ConnectionTypeWebsocket
|
|
ConnectionTypeTCP
|
|
)
|
|
|
|
var (
|
|
// ErrorFlowConnectRateLimitedKey is the Metadata entry that allows to know if a request was rate limited on connect.
|
|
ErrorFlowConnectRateLimitedKey = Metadata{Key: "FlowConnectRateLimited", Val: "true"}
|
|
)
|
|
|
|
func (c ConnectionType) String() string {
|
|
switch c {
|
|
case ConnectionTypeHTTP:
|
|
return "http"
|
|
case ConnectionTypeWebsocket:
|
|
return "ws"
|
|
case ConnectionTypeTCP:
|
|
return "tcp"
|
|
}
|
|
panic(fmt.Sprintf("invalid ConnectionType: %d", c))
|
|
}
|
|
|
|
// ConnectRequest is the representation of metadata sent at the start of a QUIC application handshake.
|
|
type ConnectRequest struct {
|
|
Dest string `capnp:"dest"`
|
|
Type ConnectionType `capnp:"type"`
|
|
Metadata []Metadata `capnp:"metadata"`
|
|
}
|
|
|
|
// Metadata is a representation of key value based data sent via RequestMeta.
|
|
type Metadata struct {
|
|
Key string `capnp:"key"`
|
|
Val string `capnp:"val"`
|
|
}
|
|
|
|
// MetadataMap returns a map format of []Metadata.
|
|
func (r *ConnectRequest) MetadataMap() map[string]string {
|
|
metadataMap := make(map[string]string)
|
|
for _, metadata := range r.Metadata {
|
|
metadataMap[metadata.Key] = metadata.Val
|
|
}
|
|
return metadataMap
|
|
}
|
|
|
|
func (r *ConnectRequest) FromPogs(msg *capnp.Message) error {
|
|
metadata, err := proto.ReadRootConnectRequest(msg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return pogs.Extract(r, proto.ConnectRequest_TypeID, metadata.Struct)
|
|
}
|
|
|
|
func (r *ConnectRequest) ToPogs() (*capnp.Message, error) {
|
|
msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
root, err := proto.NewRootConnectRequest(seg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := pogs.Insert(proto.ConnectRequest_TypeID, root.Struct, r); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return msg, nil
|
|
}
|
|
|
|
// ConnectResponse is a representation of metadata sent as a response to a QUIC application handshake.
|
|
type ConnectResponse struct {
|
|
Error string `capnp:"error"`
|
|
Metadata []Metadata `capnp:"metadata"`
|
|
}
|
|
|
|
func (r *ConnectResponse) FromPogs(msg *capnp.Message) error {
|
|
metadata, err := proto.ReadRootConnectResponse(msg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return pogs.Extract(r, proto.ConnectResponse_TypeID, metadata.Struct)
|
|
}
|
|
|
|
func (r *ConnectResponse) ToPogs() (*capnp.Message, error) {
|
|
msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
root, err := proto.NewRootConnectResponse(seg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := pogs.Insert(proto.ConnectResponse_TypeID, root.Struct, r); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return msg, nil
|
|
}
|