Trees | Indices | Help |
|
---|
|
1 #!/usr/bin/env python 2 # PySys System Test Framework, Copyright (C) 2006-2016 M.B.Grieve 3 4 # This library is free software; you can redistribute it and/or 5 # modify it under the terms of the GNU Lesser General Public 6 # License as published by the Free Software Foundation; either 7 # version 2.1 of the License, or (at your option) any later version. 8 9 # This library is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 # Lesser General Public License for more details. 13 14 # You should have received a copy of the GNU Lesser General Public 15 # License along with this library; if not, write to the Free Software 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 18 # Contact: moraygrieve@users.sourceforge.net 19 20 import collections, random, socket, sys, subprocess 21 from pysys import process_lock 22 from pysys.constants import * 23 24 # LRU queue of server TCP ports for allocation to tests which need to 25 # start TCP servers. Initialized to None since it might not actually be used. 26 # Properly initialize only on demand. 27 tcpServerPortPool = None 2830 """Returns the range of TCP ports the operating system uses to allocate 31 ephemeral ports from i.e. the ports allocated for the client side of a 32 client-server connection. Returned as a tuple, 33 (ephemeral_low, ephemeral_high) or raises exception on error. 34 """ 35 # Find the smallest and largest ephemeral port 36 if PLATFORM == 'linux': 37 f = open('/proc/sys/net/ipv4/ip_local_port_range') 38 s = f.readline().split() 39 ephemeral_low = int(s[0]) 40 ephemeral_high = int(s[1]) 41 del f 42 elif PLATFORM == 'sunos': 43 def runNdd(driver, parameter): 44 p = subprocess.Popen(['/usr/sbin/ndd', driver, parameter], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 45 return int(p.communicate()[0].strip())46 ephemeral_low = runNdd('/dev/tcp', 'tcp_smallest_anon_port') 47 ephemeral_high = runNdd('/dev/tcp', 'tcp_largest_anon_port') 48 elif PLATFORM == 'darwin': 49 def runSysctl(parameter): 50 p = subprocess.Popen(['/usr/sbin/sysctl', '-n', parameter], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 51 return int(p.communicate()[0].strip()) 52 ephemeral_low = runSysctl('net.inet.ip.portrange.first') 53 ephemeral_high = runSysctl('net.inet.ip.portrange.last') 54 elif PLATFORM == 'win32': 55 ephemeral_low = 1025 56 ephemeral_high = 5000 # The default 57 import _winreg 58 h = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters') 59 try: 60 ephemeral_high = _winreg.QueryValueEx(h, 'MaxUserPort')[0] 61 except: 62 # Accept the default if there isn't a value in the registry 63 pass 64 finally: 65 _winreg.CloseKey(h) 66 del h 67 else: 68 raise SystemError("No way of determining ephemeral port range on platform %s" % sys.platform) 69 70 return (ephemeral_low, ephemeral_high) 7173 """Initialize the pool of ports we can allocate TCP server ports from 74 i.e. ports to which processes can bind to without clashes with other 75 processes 76 """ 77 78 global tcpServerPortPool 79 80 ephemeral_low, ephemeral_high = getEphemeralTCPPortRange() 81 82 # Allocate server ports from all non-privileged, non-ephemeral ports 83 tcpServerPortPool = range(1024, ephemeral_low) + range(ephemeral_high,65536) 84 85 # Randomize the port set to reduce the chance of clashes between 86 # simultaneous runs on the same machine 87 random.shuffle(tcpServerPortPool) 88 89 # Convert to an LRU queue of ports 90 tcpServerPortPool = collections.deque(tcpServerPortPool)9193 # Try to bind to it to see if anyone else is using it 94 with process_lock: 95 s = None 96 try: 97 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 98 99 # Set SO_LINGER since we don't want any accidentally 100 # connecting clients to cause the socket to hang 101 # around 102 if OSFAMILY == 'windows': 103 s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, 0) 104 105 # Set non-blocking since we want to fail fast rather 106 # than block 107 s.setblocking(0) 108 109 # Bind to empty host i.e wildcard interface 110 try: 111 s.bind(("", port)) 112 except Exception: 113 # If we get any exception assume it is because 114 # the port is in use 115 s.close() 116 return True 117 118 # Listen may not be necessary, but on unix it seems to 119 # help do a more complete shutdown if listen is called 120 s.listen(1) 121 try: 122 s.shutdown(socket.SHUT_RDWR) 123 except Exception: 124 # Do nothing - on windows shutdown sometimes 125 # fails even after listen 126 pass 127 s.close() 128 return False 129 except Exception, e: 130 # Don't expect this but just in case 131 print 'Here', e 132 if s != None: 133 s.close() 134 return True135137 while True: 138 port = tcpServerPortPool.popleft() 139 if portIsInUse(port): 140 # Toss the port back at the end of the queue 141 tcpServerPortPool.append(port) 142 else: 143 return port144 151 152 # Initialize the TCP port pool 153 initializePortPool() 154
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Thu Jul 05 17:52:38 2018 | http://epydoc.sourceforge.net |