origin_connection.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package ingress
  2. import (
  3. "context"
  4. "io"
  5. "net"
  6. "github.com/rs/zerolog"
  7. "github.com/cloudflare/cloudflared/ipaccess"
  8. "github.com/cloudflare/cloudflared/socks"
  9. "github.com/cloudflare/cloudflared/websocket"
  10. )
  11. // OriginConnection is a way to stream to a service running on the user's origin.
  12. // Different concrete implementations will stream different protocols as long as they are io.ReadWriters.
  13. type OriginConnection interface {
  14. // Stream should generally be implemented as a bidirectional io.Copy.
  15. Stream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger)
  16. Close()
  17. }
  18. type streamHandlerFunc func(originConn io.ReadWriter, remoteConn net.Conn, log *zerolog.Logger)
  19. // DefaultStreamHandler is an implementation of streamHandlerFunc that
  20. // performs a two way io.Copy between originConn and remoteConn.
  21. func DefaultStreamHandler(originConn io.ReadWriter, remoteConn net.Conn, log *zerolog.Logger) {
  22. websocket.Stream(originConn, remoteConn, log)
  23. }
  24. // tcpConnection is an OriginConnection that directly streams to raw TCP.
  25. type tcpConnection struct {
  26. conn net.Conn
  27. }
  28. func (tc *tcpConnection) Stream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger) {
  29. websocket.Stream(tunnelConn, tc.conn, log)
  30. }
  31. func (tc *tcpConnection) Close() {
  32. tc.conn.Close()
  33. }
  34. // tcpOverWSConnection is an OriginConnection that streams to TCP over WS.
  35. type tcpOverWSConnection struct {
  36. conn net.Conn
  37. streamHandler streamHandlerFunc
  38. }
  39. func (wc *tcpOverWSConnection) Stream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger) {
  40. wc.streamHandler(websocket.NewConn(ctx, tunnelConn, log), wc.conn, log)
  41. }
  42. func (wc *tcpOverWSConnection) Close() {
  43. wc.conn.Close()
  44. }
  45. // socksProxyOverWSConnection is an OriginConnection that streams SOCKS connections over WS.
  46. // The connection to the origin happens inside the SOCKS code as the client specifies the origin
  47. // details in the packet.
  48. type socksProxyOverWSConnection struct {
  49. accessPolicy *ipaccess.Policy
  50. }
  51. func (sp *socksProxyOverWSConnection) Stream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger) {
  52. socks.StreamNetHandler(websocket.NewConn(ctx, tunnelConn, log), sp.accessPolicy, log)
  53. }
  54. func (sp *socksProxyOverWSConnection) Close() {
  55. }
  56. // wsProxyConnection represents a bidirectional stream for a websocket connection to the origin
  57. type wsProxyConnection struct {
  58. rwc io.ReadWriteCloser
  59. }
  60. func (conn *wsProxyConnection) Stream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger) {
  61. websocket.Stream(tunnelConn, conn.rwc, log)
  62. }
  63. func (conn *wsProxyConnection) Close() {
  64. conn.rwc.Close()
  65. }