portforward.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. A simple port forwarder.
  5. """
  6. # Twisted imports
  7. from twisted.internet import protocol
  8. from twisted.python import log
  9. class Proxy(protocol.Protocol):
  10. noisy = True
  11. peer = None
  12. def setPeer(self, peer):
  13. self.peer = peer
  14. def connectionLost(self, reason):
  15. if self.peer is not None:
  16. self.peer.transport.loseConnection()
  17. self.peer = None
  18. elif self.noisy:
  19. log.msg("Unable to connect to peer: %s" % (reason,))
  20. def dataReceived(self, data):
  21. self.peer.transport.write(data)
  22. class ProxyClient(Proxy):
  23. def connectionMade(self):
  24. self.peer.setPeer(self)
  25. # Wire this and the peer transport together to enable
  26. # flow control (this stops connections from filling
  27. # this proxy memory when one side produces data at a
  28. # higher rate than the other can consume).
  29. self.transport.registerProducer(self.peer.transport, True)
  30. self.peer.transport.registerProducer(self.transport, True)
  31. # We're connected, everybody can read to their hearts content.
  32. self.peer.transport.resumeProducing()
  33. class ProxyClientFactory(protocol.ClientFactory):
  34. protocol = ProxyClient
  35. def setServer(self, server):
  36. self.server = server
  37. def buildProtocol(self, *args, **kw):
  38. prot = protocol.ClientFactory.buildProtocol(self, *args, **kw)
  39. prot.setPeer(self.server)
  40. return prot
  41. def clientConnectionFailed(self, connector, reason):
  42. self.server.transport.loseConnection()
  43. class ProxyServer(Proxy):
  44. clientProtocolFactory = ProxyClientFactory
  45. reactor = None
  46. def connectionMade(self):
  47. # Don't read anything from the connecting client until we have
  48. # somewhere to send it to.
  49. self.transport.pauseProducing()
  50. client = self.clientProtocolFactory()
  51. client.setServer(self)
  52. if self.reactor is None:
  53. from twisted.internet import reactor
  54. self.reactor = reactor
  55. self.reactor.connectTCP(self.factory.host, self.factory.port, client)
  56. class ProxyFactory(protocol.Factory):
  57. """
  58. Factory for port forwarder.
  59. """
  60. protocol = ProxyServer
  61. def __init__(self, host, port):
  62. self.host = host
  63. self.port = port