server_proxy.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package marionette
  2. import (
  3. "io"
  4. "net"
  5. "sync"
  6. "github.com/armon/go-socks5"
  7. "go.uber.org/zap"
  8. )
  9. // ServerProxy represents a proxy between a marionette listener and another server.
  10. type ServerProxy struct {
  11. ln *Listener
  12. wg sync.WaitGroup
  13. // Host and port to proxy requests to.
  14. // Ignored if a socks5 server is enabled.
  15. Addr string
  16. // Server used for proxying requests.
  17. Socks5Server *socks5.Server
  18. }
  19. // NewServerProxy returns a new instance of ServerProxy.
  20. func NewServerProxy(ln *Listener) *ServerProxy {
  21. return &ServerProxy{ln: ln}
  22. }
  23. func (p *ServerProxy) Open() error {
  24. p.wg.Add(1)
  25. go func() { defer p.wg.Done(); p.run() }()
  26. return nil
  27. }
  28. func (p *ServerProxy) Close() error {
  29. return nil
  30. }
  31. func (p *ServerProxy) run() {
  32. Logger.Debug("server proxy: listening")
  33. defer Logger.Debug("server proxy: closed")
  34. for {
  35. conn, err := p.ln.Accept()
  36. if err != nil {
  37. Logger.Debug("server proxy: listener error", zap.Error(err))
  38. return
  39. }
  40. p.wg.Add(1)
  41. go func() { defer p.wg.Done(); p.handleConn(conn) }()
  42. }
  43. }
  44. func (p *ServerProxy) handleConn(conn net.Conn) {
  45. defer conn.Close()
  46. Logger.Debug("server proxy: connection open")
  47. defer Logger.Debug("server proxy: connection closed")
  48. // If the proxy address is "socks5" then hand off to socks5 server.
  49. if p.Socks5Server != nil {
  50. if err := p.Socks5Server.ServeConn(conn); err != nil {
  51. Logger.Debug("server proxy: socks5 error", zap.Error(err))
  52. }
  53. return
  54. }
  55. // Connect to remote server.
  56. proxyConn, err := net.Dial("tcp", p.Addr)
  57. if err != nil {
  58. Logger.Debug("server proxy: cannot connect to remote server", zap.String("address", p.Addr))
  59. return
  60. }
  61. defer proxyConn.Close()
  62. // Copy between connection and proxy until an error occurs.
  63. var wg sync.WaitGroup
  64. wg.Add(2)
  65. go func() {
  66. defer wg.Done()
  67. io.Copy(proxyConn, conn)
  68. proxyConn.Close()
  69. }()
  70. go func() {
  71. defer wg.Done()
  72. io.Copy(conn, proxyConn)
  73. }()
  74. wg.Wait()
  75. }