def create_tcp_socket(server_ip, server_port, connect_timeout): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock') socket_id = generate_socket_id() fdsock.sendall('OPEN TCP,%s,%s,%s,%s\n' % (socket_id, server_ip, server_port, connect_timeout * 1000)) gevent.socket.wait_read(fdsock.fileno()) fd = _multiprocessing.recvfd(fdsock.fileno()) if fd == 1: LOGGER.error('failed to create tcp socket: %s:%s' % (server_ip, server_port)) raise Exception('failed to create tcp socket: %s:%s' % (server_ip, server_port)) sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) orig_close = sock.close def close(): try: return orig_close() finally: fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock') fdsock.sendall('CLOSE TCP,%s\n' % socket_id) sock.close = close return sock
def create_udp_socket(): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock') socket_id = generate_socket_id() fdsock.sendall('OPEN UDP,%s\n' % socket_id) gevent.socket.wait_read(fdsock.fileno()) fd = _multiprocessing.recvfd(fdsock.fileno()) if fd == 1: LOGGER.error('failed to create udp socket') raise Exception('failed to create udp socket') sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_DGRAM) orig_close = sock.close def close(): try: return orig_close() finally: fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock') fdsock.sendall('CLOSE UDP,%s\n' % socket_id) sock.close = close return sock
def sock_connect_vpn(self, addr): # if LOGGER.isEnabledFor(logging.DEBUG): # LOGGER.info('vpn socket connect %s' % str(addr)) if protect_socket == False or vpn_mode == False or self.type != socket.SOCK_STREAM: return original_socket_connect(self, addr) if self.family != socket.AF_INET: return original_socket_connect(self, addr) host,port = addr if host == '127.0.0.1': return original_socket_connect(self, addr) # if LOGGER.isEnabledFor(logging.DEBUG): # LOGGER.debug("vpn tcp %s:%s" % (host, port)) fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): timeout = self.gettimeout() fdsock.connect('\0fdsock2') fdsock.sendall('OPEN TCP,%s,%s,%s\n' % (host, port,int(timeout * 1000) if timeout else 5000)) fd = _multiprocessing.recvfd(fdsock.fileno()) # if LOGGER.isEnabledFor(logging.DEBUG): # LOGGER.debug("vpn tcp %s:%s,rev fd, fd=%s, timeout=%s" % (host, port, fd, timeout)) if fd <= 2: if LOGGER.isEnabledFor(logging.DEBUG): LOGGER.error('vpn fail to create tcp socket: %s:%s, wrong fd' % (host, port)) raise socket.error('vpn fail to create tcp socket: %s:%s' % (host, port)) sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) os.close(fd) sock.settimeout(timeout) for option in _sock_options: val = socket.socket.getsockopt(self, socket.SOL_SOCKET, option, MAX_SOCK_OPTION_LEN) if val: _socket.socket.setsockopt(sock, socket.SOL_SOCKET, option, val) self._sock = sock if LOGGER.isEnabledFor(logging.DEBUG): LOGGER.debug('vpn create tcp socket OK: %s:%s' % (host, port))
def sock_init_vpn(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None): if protect_socket == False \ or vpn_mode == False \ or type != socket.SOCK_DGRAM \ or family != socket.AF_INET: original_socket_init(self, family, type, proto, _sock) return fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock2') fdsock.sendall('OPEN UDP\n') fd = _multiprocessing.recvfd(fdsock.fileno()) if fd <= 2: if LOGGER.isEnabledFor(logging.DEBUG): LOGGER.error('vpn fail to create udp socket') raise socket.error('vpn fail to create udp socket') sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_DGRAM) os.close(fd) self._sock = sock if LOGGER.isEnabledFor(logging.DEBUG): LOGGER.debug("vpn create udp socket OK")
def create_tcp_socket(server_ip, server_port, connect_timeout): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock') socket_id = generate_socket_id() fdsock.sendall( 'OPEN TCP,%s,%s,%s,%s\n' % (socket_id, server_ip, server_port, connect_timeout * 1000)) gevent.socket.wait_read(fdsock.fileno()) fd = _multiprocessing.recvfd(fdsock.fileno()) if fd == 1: LOGGER.error('failed to create tcp socket: %s:%s' % (server_ip, server_port)) raise Exception('failed to create tcp socket: %s:%s' % (server_ip, server_port)) sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) orig_close = sock.close def close(): try: return orig_close() finally: fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock') fdsock.sendall('CLOSE TCP,%s\n' % socket_id) sock.close = close return sock
def _read_fds(self, conn): # Per http://ptspts.blogspot.com/2013/08/how-to-send-unix-file-descriptors.html: # # """ # Be careful: there is no EOF handling in # _multiprocessing.recvfd (because it's buggy). On EOF, it # returns an arbitrary file descriptor number. We work it # around by doing a regular sendall--recv pair first, so if # there is an obvious reason for failure, they will fail # properly. # """ # # In our case, we already read some bytes (for argc), so # there's no value-add with duplicating their sendall--recv # strategy. stdin = os.fdopen(_multiprocessing.recvfd(conn.fileno())) stdout = os.fdopen(_multiprocessing.recvfd(conn.fileno()), 'w') stderr = os.fdopen(_multiprocessing.recvfd(conn.fileno()), 'w') return stdin, stdout, stderr
def create_udp_socket(): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock2') fdsock.sendall('OPEN UDP\n') gevent.socket.wait_read(fdsock.fileno()) fd = _multiprocessing.recvfd(fdsock.fileno()) if fd == 1: LOGGER.error('failed to create udp socket') raise socket.error('failed to create udp socket') sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_DGRAM) os.close(fd) return sock
def create_tcp_socket(server_ip, server_port, connect_timeout): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock2') fdsock.sendall('OPEN TCP,%s,%s,%s\n' % (server_ip, server_port, connect_timeout * 1000)) gevent.socket.wait_read(fdsock.fileno()) fd = _multiprocessing.recvfd(fdsock.fileno()) if fd <=2 : LOGGER.error('failed to create tcp socket: %s:%s' % (server_ip, server_port)) raise socket.error('failed to create tcp socket: %s:%s' % (server_ip, server_port)) sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) os.close(fd) return sock
def create_tcp_socket(server_ip, server_port, connect_timeout): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect('\0fdsock2') fdsock.sendall('OPEN TCP,%s,%s,%s\n' % (server_ip, server_port, connect_timeout * 1000)) gevent.socket.wait_read(fdsock.fileno()) fd = _multiprocessing.recvfd(fdsock.fileno()) if fd == 1: LOGGER.error('failed to create tcp socket: %s:%s' % (server_ip, server_port)) raise socket.error('failed to create tcp socket: %s:%s' % (server_ip, server_port)) sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) os.close(fd) return sock
def listen(address): cnx = Client(address) while True: try: args, num_fds = cnx.recv() except EOFError: break fds = dict((idx, _multiprocessing.recvfd(cnx.fileno())) for idx in range(num_fds)) proc = _PyPopen(*args, _fd_map=fds) stdout, stderr = proc.communicate() retcode = proc.poll() cnx.send((retcode, stdout, stderr))
def read_tun_fd(): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): try: fdsock.connect('\0fdsock2') fdsock.sendall('TUN\n') gevent.socket.wait_read(fdsock.fileno()) tun_fd = _multiprocessing.recvfd(fdsock.fileno()) if tun_fd == 1: LOGGER.error('received invalid tun fd') return None return tun_fd except: return None
def create_udp_socket(): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): fdsock.connect("\0fdsock2") socket_id = generate_socket_id() fdsock.sendall("OPEN UDP,%s\n" % socket_id) gevent.socket.wait_read(fdsock.fileno()) fd = _multiprocessing.recvfd(fdsock.fileno()) if fd == 1: LOGGER.error("failed to create udp socket") raise Exception("failed to create udp socket") sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_DGRAM) os.close(fd) return sock
def read_tun_fd(): fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): try: fdsock.connect('\0fdsock2') fdsock.sendall('TUN\n') gevent.socket.wait_read(fdsock.fileno(), timeout=3) tun_fd = _multiprocessing.recvfd(fdsock.fileno()) if tun_fd == 1: LOGGER.error('received invalid tun fd') return None return tun_fd except: return None
def listen(address): cnx = Client(address) while True: try: args, num_fds = cnx.recv() except EOFError: break fds = dict( (idx, _multiprocessing.recvfd(cnx.fileno())) for idx in range(num_fds) ) proc = _PyPopen(*args, _fd_map=fds) stdout, stderr = proc.communicate() retcode = proc.poll() cnx.send((retcode, stdout, stderr))
def get_fd_for_address(self, bind_address): self.send_str('REQ_FD') self.send_str(bind_string(bind_address)) response = self.recv_str() if response == 'OK': # NOTE: it seems fairly common to get an EGAIN on this read. the # underlying socket is in non-blocking mode, but i'm not sure why this # operation in particular seems to need a retry. for i in xrange(3): try: return _multiprocessing.recvfd(self.socket.fileno()) except OSError, e: if e[0] == errno.EAGAIN: time.sleep(0.050) else: raise raise e
def read_tun_fd(): LOGGER.info('connecting to fdsock') while True: fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): try: fdsock.connect('\0fdsock2') LOGGER.info('connected to fdsock2') fdsock.sendall('TUN\n') gevent.socket.wait_read(fdsock.fileno()) tun_fd=_multiprocessing.recvfd(fdsock.fileno()) if tun_fd == 1: LOGGER.error('received invalid tun fd') continue return tun_fd except: LOGGER.info('retry in 3 seconds') gevent.sleep(3)
def read_tun_fd(): LOGGER.info('connecting to fdsock') while True: fdsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) with contextlib.closing(fdsock): try: fdsock.connect('\0fdsock') LOGGER.info('connected to fdsock') fdsock.sendall('TUN\n') gevent.socket.wait_read(fdsock.fileno()) tun_fd = _multiprocessing.recvfd(fdsock.fileno()) if tun_fd == 1: LOGGER.error('received invalid tun fd') continue return tun_fd except: LOGGER.info('retry in 3 seconds') gevent.sleep(3)
def recv_handle(conn): return _multiprocessing.recvfd(conn.fileno())
sendfd(connection.fileno(), f_no) except: print >>sys.stderr, 'failed to send file descriptor' sys.exit(2) try: connection.close() except: pass else: try: print >>sys.stderr, 'connecting to ' + uds_name sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) connection = sock.connect(uds_name) except: print >>sys.stderr, 'failed to connect' raise sys.exit(2) try: print >>sys.stderr, 'receiving file descriptor' fd = recvfd(sock.fileno()) except: print >>sys.stderr, 'failed to receive file descriptor' sys.exit(2) print >>sys.stderr, 'dumping contents' istream = io.open(fd,"rb",closefd=True) shutil.copyfileobj(istream, sys.stdout) istream.close()
def serve_forever(self): # keep track of scripts we have run script_set = set() while True: try: # This needs a separate thread loop to keep the zombies at bay. while os.waitpid(-1, os.WNOHANG)[0]: pass except OSError, e: if e[0] != errno.ECHILD: raise client_sock, addr = self.sock.accept() env = self.recv_str(client_sock) client_env = {} for line in env.split('\n'): line = line.strip() if line: key, value = line.split('=', 1) client_env[key] = value old_env = os.environ.copy() old_sys_path = sys.path[:] os.environ.update(client_env) argc = self.recv_int(client_sock) argv = [self.recv_str(client_sock) for x in range(argc)] script = os.path.abspath(argv[1]) # Only fork when we have already loaded code for this # application into this interpreter. fork = (script in script_set) #fork = True script_set.add(script) if fork and os.fork() != 0: # parent process, just go waitpid continue # child process, or the main process when we first cache if client_env.get('PYTHONPATH', ''): sys.path[0:0] = client_env.get('PYTHONPATH', '').split(':') #print >> sys.stderr, script, 'fork', fork, client_env, argc, argv try: fd = client_sock.fileno() stdin_fd = _multiprocessing.recvfd(fd) stdout_fd = _multiprocessing.recvfd(fd) stderr_fd = _multiprocessing.recvfd(fd) sys.stdin = os.fdopen(stdin_fd, 'r') sys.stdout = os.fdopen(stdout_fd, 'w') sys.stderr = os.fdopen(stderr_fd, 'w') sys.argv = argv[1:] sys.exit = pyzy_exit os.chdir(os.environ['PWD']) except Exception as e: print >> sys.stderr, e if fork: os._exit(0) pid = os.getpid() client_sock.send(struct.pack('!I', pid)) return_code = 0 try: try: # Post-fork, this goes to the client. Need a log file. # print >> sys.stderr, "module count preload:", len([name for name, mod in sys.modules.iteritems() if mod]) execfile(argv[1]) except PyZySystemExit, e: return_code = e[0] except Exception, e: print >> sys.stderr, e return_code = 1
def recvfds(conn, num): return [_multiprocessing.recvfd(conn.fileno()) for _ in range(num)]
sendfd(connection.fileno(), f_no) except: print >> sys.stderr, 'failed to send file descriptor' sys.exit(2) try: connection.close() except: pass else: try: print >> sys.stderr, 'connecting to ' + uds_name sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) connection = sock.connect(uds_name) except: print >> sys.stderr, 'failed to connect' raise sys.exit(2) try: print >> sys.stderr, 'receiving file descriptor' fd = recvfd(sock.fileno()) except: print >> sys.stderr, 'failed to receive file descriptor' sys.exit(2) print >> sys.stderr, 'dumping contents' istream = io.open(fd, "rb", closefd=True) shutil.copyfileobj(istream, sys.stdout) istream.close()