def work(self): Worker.work(self) while self.running: client = self.connectRequestsQueue.get() self.say("New client: %s " % client) proxy = self.__getProxy() if proxy: self.say("Forwarding to next proxy: %s" % str(proxy)) self.forwardingQueue.put(Connection(client, proxy).reduce()) continue else: # direct connection self.say("No proxy found, making direct connection") client.rebuild() buf = client.socket.recv(BUFFER_SIZE) self.say("Received %s from %s " % (buf, client)) if not buf: client.shutdown() continue httpRequest = HttpRequest.buildFromBuffer(buf) if httpRequest.requestType == "CONNECT": host, port = httpRequest.requestedResource.split(":") self.say("Tunneling to: %s:%s" % (host, port)) try: server = Endpoint.connectTo(Address(host, port)) except socket.error, why: sys.stderr.write(why.message + "\n") client.shutdown() continue client.socket.sendall( "HTTP/1.1 200 Connection established\r\nProxy-Agent: TunaPy/0.1\r\n\r\n" ) self.forwardingQueue.put( Connection(client, server).reduce()) continue else: httpRequest.makeRelative() host = httpRequest.options['Host'] port = 80 address = Address(host, port) self.say('Sending to %s' % address) try: server = Endpoint.connectTo(address) # resend the client HTTP request to the server self.say("Sending: %s" % httpRequest.toBuffer()) server.socket.sendall(httpRequest.toBuffer()) except socket.error, why: sys.stderr.write('An error occurred:\n%s\n' % why.message) client.shutdown() continue self.say("Proxying queue size: %d" % self.proxyingQueue.qsize()) conn = Connection(client, server).reduce() self.proxyingQueue.put(conn)
def work(self): Worker.work(self) while self.running: client = self.connectRequestsQueue.get() self.say("New client: %s " % client) proxy = self.__getProxy() if proxy: self.say("Forwarding to next proxy: %s" % str(proxy)) self.forwardingQueue.put( Connection(client, proxy).reduce()) continue else: # direct connection self.say("No proxy found, making direct connection") client.rebuild() buf = client.socket.recv(BUFFER_SIZE) self.say("Received %s from %s " % (buf ,client)) if not buf: client.shutdown() continue httpRequest = HttpRequest.buildFromBuffer(buf) if httpRequest.requestType == "CONNECT": host, port = httpRequest.requestedResource.split(":") self.say("Tunneling to: %s:%s" % (host, port)) try: server = Endpoint.connectTo(Address(host, port)) except socket.error, why: sys.stderr.write(why.message + "\n") client.shutdown() continue client.socket.sendall("HTTP/1.1 200 Connection established\r\nProxy-Agent: TunaPy/0.1\r\n\r\n") self.forwardingQueue.put( Connection(client, server).reduce()) continue else: httpRequest.makeRelative() host = httpRequest.options['Host'] port = 80 address = Address(host, port) self.say('Sending to %s' % address) try: server = Endpoint.connectTo(address) # resend the client HTTP request to the server self.say("Sending: %s" % httpRequest.toBuffer()) server.socket.sendall(httpRequest.toBuffer()) except socket.error, why: sys.stderr.write('An error occurred:\n%s\n' % why.message) client.shutdown() continue self.say("Proxying queue size: %d" % self.proxyingQueue.qsize()) conn = Connection(client, server).reduce() self.proxyingQueue.put(conn)
def __getProxy(self): """ Tries to find a reachable proxy. Makes it first proxy if found. """ proxyList = [] if self.sharedConfig: host, port = self.getConfig().get("config", "forward").split(':') proxyList.append(Address(host, port)) for proxy in self.proxyList + proxyList: try: return Endpoint.connectTo(proxy) except socket.error: self.say("Failed to connect to proxy %s" % str(proxy)) return None
def __getProxy(self): """ Tries to find a reachable proxy. Makes it first proxy if found. """ proxyList = [] if self.sharedConfig: host,port = self.getConfig().get("config", "forward").split(':') proxyList.append(Address(host,port)) for proxy in self.proxyList + proxyList: try: return Endpoint.connectTo(proxy) except socket.error: self.say("Failed to connect to proxy %s" % str(proxy)) return None
def _processBuffer(self, readable, buf): conn = self.socket2conn[readable] if conn.client.socket is readable: httpRequest= HttpRequest.buildFromBuffer(buf) address = Address(httpRequest.options['Host'], 80) if address.host is not None and (address.host, address.port) != conn.server.address: # observed behaviour was that a client may try to reuse a connection but with a different server # when this is the case the old server connection is replaced with the new one self.say("New connection requested to %s from %s" % (address,conn)) self._removeConnection(conn) conn.server.shutdown() try: conn.server= Endpoint.connectTo(address) except socket.error, why: sys.stderr.write("Failed to setup connection to %s, reason: %s" % (address,why) ) return self._addConnection(conn) httpRequest.makeRelative() conn.server.socket.sendall(httpRequest.toBuffer())
def _processBuffer(self, readable, buf): conn = self.socket2conn[readable] if conn.client.socket is readable: httpRequest = HttpRequest.buildFromBuffer(buf) address = Address(httpRequest.options['Host'], 80) if address.host is not None and ( address.host, address.port) != conn.server.address: # observed behaviour was that a client may try to reuse a connection but with a different server # when this is the case the old server connection is replaced with the new one self.say("New connection requested to %s from %s" % (address, conn)) self._removeConnection(conn) conn.server.shutdown() try: conn.server = Endpoint.connectTo(address) except socket.error, why: sys.stderr.write( "Failed to setup connection to %s, reason: %s" % (address, why)) return self._addConnection(conn) httpRequest.makeRelative() conn.server.socket.sendall(httpRequest.toBuffer())
def main(): options, remainingArgs = ProxyOptions().parse_args() listenAddress = options.listen or LISTEN_ADDRESS listenPort = options.port or LISTEN_PORT statusQueue = JoinableQueue(20) sharedConfig = Array('c', 100) processes = [] proxyList = [] if options.forward: print('Will forward to: %s' % options.forward) for proxy in options.forward: host, port = proxy.split(":") proxyList.append(Address(host, port)) elif options.proxycfg: if not os.path.isfile(options.proxycfg): raise ValueError("No such file: %s" % options.proxycfg) cfgUpdater = ConfigUpdater(options.proxycfg, sharedConfig, statusQueue) p = Process(target=cfgUpdater.work, args=()) processes.append(p) p.start() print('Forwarding to proxies: %s' % str(proxyList)) signal.signal(signal.SIGTERM, signalHandler) connectRequestsQueue = JoinableQueue(20) forwardingQueue = JoinableQueue(20) proxyingQueue = JoinableQueue(20) print("Starting workers...") workers = [ SwitchWorker("Adam", connectRequestsQueue, forwardingQueue, proxyingQueue), ForwardingWorker("Fred", forwardingQueue), DirectProxyWorker("Perseus", proxyingQueue), DirectProxyWorker("Penelope1", proxyingQueue), DirectProxyWorker("Penelope2", proxyingQueue), DirectProxyWorker("Penelope3", proxyingQueue), MonitorWorker("Mo"), ] for worker in workers: if isinstance(worker, SwitchWorker): worker.proxyList = proxyList worker.statusQueue = statusQueue worker.sharedConfig = sharedConfig p = Process(target=worker.work, args=()) processes.append(p) p.start() listeningSocket = Socket(socket.AF_INET, socket.SOCK_STREAM, proto=socket.IPPROTO_TCP) listeningSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listeningSocket.bind((listenAddress, listenPort)) listeningSocket.listen(10) print("Listening on %s:%d" % (listenAddress, listenPort)) try: while running: clientSocket, clientAddress = listeningSocket.accept() client = Endpoint(clientSocket, clientAddress) connectRequestsQueue.put(client.reduce()) except KeyboardInterrupt: print("Quitting... requested by user") finally: listeningSocket.close() #wait for all of the child processes # TODO: should stop the processes if quitting not user requested print("Waiting for child processes...") for p in processes: p.join() print("Done!") return 0
def main(): options, remainingArgs = ProxyOptions().parse_args() listenAddress = options.listen or LISTEN_ADDRESS listenPort = options.port or LISTEN_PORT statusQueue = JoinableQueue(20) sharedConfig = Array('c', 100) processes = [] proxyList = [] if options.forward: print('Will forward to: %s' % options.forward) for proxy in options.forward: host, port = proxy.split(":") proxyList.append( Address(host, port)) elif options.proxycfg: if not os.path.isfile(options.proxycfg): raise ValueError("No such file: %s" % options.proxycfg) cfgUpdater = ConfigUpdater(options.proxycfg, sharedConfig, statusQueue) p = Process(target=cfgUpdater.work, args=()) processes.append(p) p.start() print('Forwarding to proxies: %s' % str(proxyList)) signal.signal(signal.SIGTERM, signalHandler) connectRequestsQueue = JoinableQueue(20) forwardingQueue = JoinableQueue(20) proxyingQueue = JoinableQueue(20) print("Starting workers...") workers = [ SwitchWorker("Adam", connectRequestsQueue, forwardingQueue, proxyingQueue), ForwardingWorker("Fred", forwardingQueue), DirectProxyWorker("Perseus", proxyingQueue), DirectProxyWorker("Penelope1", proxyingQueue), DirectProxyWorker("Penelope2", proxyingQueue), DirectProxyWorker("Penelope3", proxyingQueue), MonitorWorker("Mo"), ] for worker in workers: if isinstance(worker, SwitchWorker): worker.proxyList = proxyList worker.statusQueue = statusQueue worker.sharedConfig = sharedConfig p = Process(target=worker.work, args=()) processes.append(p) p.start() listeningSocket = Socket(socket.AF_INET, socket.SOCK_STREAM, proto=socket.IPPROTO_TCP) listeningSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listeningSocket.bind((listenAddress, listenPort)) listeningSocket.listen(10) print("Listening on %s:%d" % (listenAddress, listenPort)) try: while running: clientSocket, clientAddress = listeningSocket.accept() client = Endpoint(clientSocket, clientAddress) connectRequestsQueue.put(client.reduce()) except KeyboardInterrupt: print("Quitting... requested by user") finally: listeningSocket.close() #wait for all of the child processes # TODO: should stop the processes if quitting not user requested print("Waiting for child processes...") for p in processes: p.join() print("Done!") return 0