tunnelrpc.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. package pogs
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/cloudflare/cloudflared/tunnelrpc"
  6. capnp "zombiezen.com/go/capnproto2"
  7. "zombiezen.com/go/capnproto2/pogs"
  8. "zombiezen.com/go/capnproto2/rpc"
  9. "zombiezen.com/go/capnproto2/server"
  10. )
  11. const (
  12. defaultRetryAfterSeconds = 15
  13. )
  14. type Authentication struct {
  15. Key string
  16. Email string
  17. OriginCAKey string
  18. }
  19. func MarshalAuthentication(s tunnelrpc.Authentication, p *Authentication) error {
  20. return pogs.Insert(tunnelrpc.Authentication_TypeID, s.Struct, p)
  21. }
  22. func UnmarshalAuthentication(s tunnelrpc.Authentication) (*Authentication, error) {
  23. p := new(Authentication)
  24. err := pogs.Extract(p, tunnelrpc.Authentication_TypeID, s.Struct)
  25. return p, err
  26. }
  27. type TunnelRegistration struct {
  28. SuccessfulTunnelRegistration
  29. Err string
  30. PermanentFailure bool
  31. RetryAfterSeconds uint16
  32. }
  33. type SuccessfulTunnelRegistration struct {
  34. Url string
  35. LogLines []string
  36. TunnelID string `capnp:"tunnelID"`
  37. EventDigest []byte
  38. ConnDigest []byte
  39. }
  40. func NewSuccessfulTunnelRegistration(
  41. url string,
  42. logLines []string,
  43. tunnelID string,
  44. eventDigest []byte,
  45. connDigest []byte,
  46. ) *TunnelRegistration {
  47. // Marshal nil will result in an error
  48. if logLines == nil {
  49. logLines = []string{}
  50. }
  51. return &TunnelRegistration{
  52. SuccessfulTunnelRegistration: SuccessfulTunnelRegistration{
  53. Url: url,
  54. LogLines: logLines,
  55. TunnelID: tunnelID,
  56. EventDigest: eventDigest,
  57. ConnDigest: connDigest,
  58. },
  59. }
  60. }
  61. // Not calling this function Error() to avoid confusion with implementing error interface
  62. func (tr TunnelRegistration) DeserializeError() TunnelRegistrationError {
  63. if tr.Err != "" {
  64. err := fmt.Errorf(tr.Err)
  65. if tr.PermanentFailure {
  66. return NewPermanentRegistrationError(err)
  67. }
  68. retryAfterSeconds := tr.RetryAfterSeconds
  69. if retryAfterSeconds < defaultRetryAfterSeconds {
  70. retryAfterSeconds = defaultRetryAfterSeconds
  71. }
  72. return NewRetryableRegistrationError(err, retryAfterSeconds)
  73. }
  74. return nil
  75. }
  76. type TunnelRegistrationError interface {
  77. error
  78. Serialize() *TunnelRegistration
  79. IsPermanent() bool
  80. }
  81. type PermanentRegistrationError struct {
  82. err string
  83. }
  84. func NewPermanentRegistrationError(err error) TunnelRegistrationError {
  85. return &PermanentRegistrationError{
  86. err: err.Error(),
  87. }
  88. }
  89. func (pre *PermanentRegistrationError) Error() string {
  90. return pre.err
  91. }
  92. func (pre *PermanentRegistrationError) Serialize() *TunnelRegistration {
  93. return &TunnelRegistration{
  94. Err: pre.err,
  95. PermanentFailure: true,
  96. }
  97. }
  98. func (*PermanentRegistrationError) IsPermanent() bool {
  99. return true
  100. }
  101. type RetryableRegistrationError struct {
  102. err string
  103. retryAfterSeconds uint16
  104. }
  105. func NewRetryableRegistrationError(err error, retryAfterSeconds uint16) TunnelRegistrationError {
  106. return &RetryableRegistrationError{
  107. err: err.Error(),
  108. retryAfterSeconds: retryAfterSeconds,
  109. }
  110. }
  111. func (rre *RetryableRegistrationError) Error() string {
  112. return rre.err
  113. }
  114. func (rre *RetryableRegistrationError) Serialize() *TunnelRegistration {
  115. return &TunnelRegistration{
  116. Err: rre.err,
  117. PermanentFailure: false,
  118. RetryAfterSeconds: rre.retryAfterSeconds,
  119. }
  120. }
  121. func (*RetryableRegistrationError) IsPermanent() bool {
  122. return false
  123. }
  124. func MarshalTunnelRegistration(s tunnelrpc.TunnelRegistration, p *TunnelRegistration) error {
  125. return pogs.Insert(tunnelrpc.TunnelRegistration_TypeID, s.Struct, p)
  126. }
  127. func UnmarshalTunnelRegistration(s tunnelrpc.TunnelRegistration) (*TunnelRegistration, error) {
  128. p := new(TunnelRegistration)
  129. err := pogs.Extract(p, tunnelrpc.TunnelRegistration_TypeID, s.Struct)
  130. return p, err
  131. }
  132. type RegistrationOptions struct {
  133. ClientID string `capnp:"clientId"`
  134. Version string
  135. OS string `capnp:"os"`
  136. ExistingTunnelPolicy tunnelrpc.ExistingTunnelPolicy
  137. PoolName string `capnp:"poolName"`
  138. Tags []Tag
  139. ConnectionID uint8 `capnp:"connectionId"`
  140. OriginLocalIP string `capnp:"originLocalIp"`
  141. IsAutoupdated bool `capnp:"isAutoupdated"`
  142. RunFromTerminal bool `capnp:"runFromTerminal"`
  143. CompressionQuality uint64 `capnp:"compressionQuality"`
  144. UUID string `capnp:"uuid"`
  145. NumPreviousAttempts uint8
  146. Features []string
  147. }
  148. func MarshalRegistrationOptions(s tunnelrpc.RegistrationOptions, p *RegistrationOptions) error {
  149. return pogs.Insert(tunnelrpc.RegistrationOptions_TypeID, s.Struct, p)
  150. }
  151. func UnmarshalRegistrationOptions(s tunnelrpc.RegistrationOptions) (*RegistrationOptions, error) {
  152. p := new(RegistrationOptions)
  153. err := pogs.Extract(p, tunnelrpc.RegistrationOptions_TypeID, s.Struct)
  154. return p, err
  155. }
  156. type Tag struct {
  157. Name string `json:"name"`
  158. Value string `json:"value"`
  159. }
  160. type ServerInfo struct {
  161. LocationName string
  162. }
  163. func MarshalServerInfo(s tunnelrpc.ServerInfo, p *ServerInfo) error {
  164. return pogs.Insert(tunnelrpc.ServerInfo_TypeID, s.Struct, p)
  165. }
  166. func UnmarshalServerInfo(s tunnelrpc.ServerInfo) (*ServerInfo, error) {
  167. p := new(ServerInfo)
  168. err := pogs.Extract(p, tunnelrpc.ServerInfo_TypeID, s.Struct)
  169. return p, err
  170. }
  171. type TunnelServer interface {
  172. RegistrationServer
  173. RegisterTunnel(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) *TunnelRegistration
  174. GetServerInfo(ctx context.Context) (*ServerInfo, error)
  175. UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error
  176. Authenticate(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) (*AuthenticateResponse, error)
  177. ReconnectTunnel(ctx context.Context, jwt, eventDigest, connDigest []byte, hostname string, options *RegistrationOptions) (*TunnelRegistration, error)
  178. }
  179. func TunnelServer_ServerToClient(s TunnelServer) tunnelrpc.TunnelServer {
  180. return tunnelrpc.TunnelServer_ServerToClient(TunnelServer_PogsImpl{s})
  181. }
  182. type TunnelServer_PogsImpl struct {
  183. impl TunnelServer
  184. }
  185. func (i TunnelServer_PogsImpl) RegisterTunnel(p tunnelrpc.TunnelServer_registerTunnel) error {
  186. originCert, err := p.Params.OriginCert()
  187. if err != nil {
  188. return err
  189. }
  190. hostname, err := p.Params.Hostname()
  191. if err != nil {
  192. return err
  193. }
  194. options, err := p.Params.Options()
  195. if err != nil {
  196. return err
  197. }
  198. pogsOptions, err := UnmarshalRegistrationOptions(options)
  199. if err != nil {
  200. return err
  201. }
  202. server.Ack(p.Options)
  203. registration := i.impl.RegisterTunnel(p.Ctx, originCert, hostname, pogsOptions)
  204. result, err := p.Results.NewResult()
  205. if err != nil {
  206. return err
  207. }
  208. return MarshalTunnelRegistration(result, registration)
  209. }
  210. func (i TunnelServer_PogsImpl) GetServerInfo(p tunnelrpc.TunnelServer_getServerInfo) error {
  211. server.Ack(p.Options)
  212. serverInfo, err := i.impl.GetServerInfo(p.Ctx)
  213. if err != nil {
  214. return err
  215. }
  216. result, err := p.Results.NewResult()
  217. if err != nil {
  218. return err
  219. }
  220. return MarshalServerInfo(result, serverInfo)
  221. }
  222. func (i TunnelServer_PogsImpl) UnregisterTunnel(p tunnelrpc.TunnelServer_unregisterTunnel) error {
  223. gracePeriodNanoSec := p.Params.GracePeriodNanoSec()
  224. server.Ack(p.Options)
  225. return i.impl.UnregisterTunnel(p.Ctx, gracePeriodNanoSec)
  226. }
  227. func (i TunnelServer_PogsImpl) ObsoleteDeclarativeTunnelConnect(p tunnelrpc.TunnelServer_obsoleteDeclarativeTunnelConnect) error {
  228. return fmt.Errorf("RPC to create declarative tunnel connection has been deprecated")
  229. }
  230. type TunnelServer_PogsClient struct {
  231. Client capnp.Client
  232. Conn *rpc.Conn
  233. }
  234. func (c TunnelServer_PogsClient) Close() error {
  235. c.Client.Close()
  236. return c.Conn.Close()
  237. }
  238. func (c TunnelServer_PogsClient) RegisterTunnel(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) *TunnelRegistration {
  239. client := tunnelrpc.TunnelServer{Client: c.Client}
  240. promise := client.RegisterTunnel(ctx, func(p tunnelrpc.TunnelServer_registerTunnel_Params) error {
  241. err := p.SetOriginCert(originCert)
  242. if err != nil {
  243. return err
  244. }
  245. err = p.SetHostname(hostname)
  246. if err != nil {
  247. return err
  248. }
  249. registrationOptions, err := p.NewOptions()
  250. if err != nil {
  251. return err
  252. }
  253. err = MarshalRegistrationOptions(registrationOptions, options)
  254. if err != nil {
  255. return err
  256. }
  257. return nil
  258. })
  259. retval, err := promise.Result().Struct()
  260. if err != nil {
  261. return NewRetryableRegistrationError(err, defaultRetryAfterSeconds).Serialize()
  262. }
  263. registration, err := UnmarshalTunnelRegistration(retval)
  264. if err != nil {
  265. return NewRetryableRegistrationError(err, defaultRetryAfterSeconds).Serialize()
  266. }
  267. return registration
  268. }
  269. func (c TunnelServer_PogsClient) GetServerInfo(ctx context.Context) (*ServerInfo, error) {
  270. client := tunnelrpc.TunnelServer{Client: c.Client}
  271. promise := client.GetServerInfo(ctx, func(p tunnelrpc.TunnelServer_getServerInfo_Params) error {
  272. return nil
  273. })
  274. retval, err := promise.Result().Struct()
  275. if err != nil {
  276. return nil, err
  277. }
  278. return UnmarshalServerInfo(retval)
  279. }
  280. func (c TunnelServer_PogsClient) UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error {
  281. client := tunnelrpc.TunnelServer{Client: c.Client}
  282. promise := client.UnregisterTunnel(ctx, func(p tunnelrpc.TunnelServer_unregisterTunnel_Params) error {
  283. p.SetGracePeriodNanoSec(gracePeriodNanoSec)
  284. return nil
  285. })
  286. _, err := promise.Struct()
  287. return err
  288. }