quic_metadata_protocol.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package pogs
  2. import (
  3. "fmt"
  4. capnp "zombiezen.com/go/capnproto2"
  5. "zombiezen.com/go/capnproto2/pogs"
  6. "github.com/cloudflare/cloudflared/tunnelrpc/proto"
  7. )
  8. // ConnectionType indicates the type of underlying connection proxied within the QUIC stream.
  9. type ConnectionType uint16
  10. const (
  11. ConnectionTypeHTTP ConnectionType = iota
  12. ConnectionTypeWebsocket
  13. ConnectionTypeTCP
  14. )
  15. func (c ConnectionType) String() string {
  16. switch c {
  17. case ConnectionTypeHTTP:
  18. return "http"
  19. case ConnectionTypeWebsocket:
  20. return "ws"
  21. case ConnectionTypeTCP:
  22. return "tcp"
  23. }
  24. panic(fmt.Sprintf("invalid ConnectionType: %d", c))
  25. }
  26. // ConnectRequest is the representation of metadata sent at the start of a QUIC application handshake.
  27. type ConnectRequest struct {
  28. Dest string `capnp:"dest"`
  29. Type ConnectionType `capnp:"type"`
  30. Metadata []Metadata `capnp:"metadata"`
  31. }
  32. // Metadata is a representation of key value based data sent via RequestMeta.
  33. type Metadata struct {
  34. Key string `capnp:"key"`
  35. Val string `capnp:"val"`
  36. }
  37. // MetadataMap returns a map format of []Metadata.
  38. func (r *ConnectRequest) MetadataMap() map[string]string {
  39. metadataMap := make(map[string]string)
  40. for _, metadata := range r.Metadata {
  41. metadataMap[metadata.Key] = metadata.Val
  42. }
  43. return metadataMap
  44. }
  45. func (r *ConnectRequest) FromPogs(msg *capnp.Message) error {
  46. metadata, err := proto.ReadRootConnectRequest(msg)
  47. if err != nil {
  48. return err
  49. }
  50. return pogs.Extract(r, proto.ConnectRequest_TypeID, metadata.Struct)
  51. }
  52. func (r *ConnectRequest) ToPogs() (*capnp.Message, error) {
  53. msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
  54. if err != nil {
  55. return nil, err
  56. }
  57. root, err := proto.NewRootConnectRequest(seg)
  58. if err != nil {
  59. return nil, err
  60. }
  61. if err := pogs.Insert(proto.ConnectRequest_TypeID, root.Struct, r); err != nil {
  62. return nil, err
  63. }
  64. return msg, nil
  65. }
  66. // ConnectResponse is a representation of metadata sent as a response to a QUIC application handshake.
  67. type ConnectResponse struct {
  68. Error string `capnp:"error"`
  69. Metadata []Metadata `capnp:"metadata"`
  70. }
  71. func (r *ConnectResponse) FromPogs(msg *capnp.Message) error {
  72. metadata, err := proto.ReadRootConnectResponse(msg)
  73. if err != nil {
  74. return err
  75. }
  76. return pogs.Extract(r, proto.ConnectResponse_TypeID, metadata.Struct)
  77. }
  78. func (r *ConnectResponse) ToPogs() (*capnp.Message, error) {
  79. msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
  80. if err != nil {
  81. return nil, err
  82. }
  83. root, err := proto.NewRootConnectResponse(seg)
  84. if err != nil {
  85. return nil, err
  86. }
  87. if err := pogs.Insert(proto.ConnectResponse_TypeID, root.Struct, r); err != nil {
  88. return nil, err
  89. }
  90. return msg, nil
  91. }