def addresses_match(addr1, addr2): """Check two network addresses for similarity Is it zero padded in one place, not zero padded in another? Is one place by name and another by IP?? Is one context getting a normal IPv4 address and another getting IPv4 in IPv6 notation? This function examines the two given names, performing the required changes to compare them for equivalency :param addr1: :param addr2: :return: True if the given addresses refer to the same thing """ for addrinfo in socket.getaddrinfo(addr1, 0, 0, socket.SOCK_STREAM): rootaddr1 = socket.inet_pton(addrinfo[0], addrinfo[4][0]) if addrinfo[ 0] == socket.AF_INET6 and rootaddr1[: 12] == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff': # normalize to standard IPv4 rootaddr1 = rootaddr1[-4:] for otherinfo in socket.getaddrinfo(addr2, 0, 0, socket.SOCK_STREAM): otheraddr = socket.inet_pton(otherinfo[0], otherinfo[4][0]) if otherinfo[ 0] == socket.AF_INET6 and otheraddr[: 12] == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff': otheraddr = otheraddr[-4:] if otheraddr == rootaddr1: return True return False
def get_socket(conf, default_port=8080): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :param default_port: port to use if not specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = (conf.get("bind_ip", "0.0.0.0"), int(conf.get("bind_port", default_port))) address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get("backlog", 4096)), family=address_family) if "cert_file" in conf: sock = ssl.wrap_socket(sock, certfile=conf["cert_file"], keyfile=conf["key_file"]) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1)
def __init__(self, *args, **kwargs): Connection.__init__(self, *args, **kwargs) self._write_queue = Queue() sockerr = None addresses = socket.getaddrinfo( self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM ) for (af, socktype, proto, canonname, sockaddr) in addresses: try: self._socket = socket.socket(af, socktype, proto) self._socket.settimeout(1.0) self._socket.connect(sockaddr) sockerr = None break except socket.error as err: sockerr = err if sockerr: raise socket.error( sockerr.errno, "Tried connecting to %s. Last error: %s" % ( [a[4] for a in addresses], sockerr.strerror) ) if self.sockopts: for args in self.sockopts: self._socket.setsockopt(*args) self._read_watcher = eventlet.spawn(lambda: self.handle_read()) self._write_watcher = eventlet.spawn(lambda: self.handle_write()) self._send_options_message()
def __init__(self, *args, **kwargs): Connection.__init__(self, *args, **kwargs) self.connected_event = Event() self._write_queue = Queue() self._callbacks = {} self._push_watchers = defaultdict(set) sockerr = None addresses = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM) for (af, socktype, proto, canonname, sockaddr) in addresses: try: self._socket = socket.socket(af, socktype, proto) self._socket.settimeout(1.0) self._socket.connect(sockaddr) sockerr = None break except socket.error as err: sockerr = err if sockerr: raise socket.error( sockerr.errno, "Tried connecting to %s. Last error: %s" % ([a[4] for a in addresses], sockerr.strerror)) if self.sockopts: for args in self.sockopts: self._socket.setsockopt(*args) self._read_watcher = eventlet.spawn(lambda: self.handle_read()) self._write_watcher = eventlet.spawn(lambda: self.handle_write()) self._send_options_message()
def get_socket(conf, default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(bind_addr)s" "after trying for 30 seconds") % {'bind_addr': bind_addr}) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) return sock
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = CONF.cert_file key_file = CONF.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError(_("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) def wrap_ssl(sock): ssl_kwargs = { 'server_side': True, 'certfile': cert_file, 'keyfile': key_file, 'cert_reqs': ssl.CERT_NONE, } if CONF.ca_file: ssl_kwargs['ca_certs'] = CONF.ca_file ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) if use_ssl: sock = wrap_ssl(sock) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1)
def get_socket(conf, default_port=8080): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :param default_port: port to use if not specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = (conf.get('bind_ip', '0.0.0.0'), int(conf.get('bind_port', default_port))) address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), family=address_family) if 'cert_file' in conf: sock = ssl.wrap_socket(sock, certfile=conf['cert_file'], keyfile=conf['key_file']) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1)
def _connect(self): err = None for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): family, socktype, proto, canonname, socket_address = res sock = None try: sock = socket.socket(family, socktype, proto) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if self.socket_keepalive: sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) for k, v in self.socket_keepalive_options.iteritems(): sock.setsockopt(socket.SOL_TCP, k, v) sock.settimeout(self.socket_connect_timeout) sock.connect(socket_address) sock.settimeout(self.socket_timeout) return sock except socket.error as _: err = _ if sock is not None: sock.close() if err is not None: raise err raise socket.error("socket.getaddrinfo returned empty list")
def _connect(self): err = None for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): family, socktype, proto, canonname, socket_address = res sock = None try: sock = socket.socket(family, socktype, proto) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if self.socket_keepalive: sock.setsockopt( socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) for k, v in self.socket_keepalive_options.iteritems(): sock.setsockopt(socket.SOL_TCP, k, v) sock.settimeout(self.socket_connect_timeout) sock.connect(socket_address) sock.settimeout(self.socket_timeout) return sock except socket.error as _: err = _ if sock is not None: sock.close() if err is not None: raise err raise socket.error("socket.getaddrinfo returned empty list")
def get_socket(conf, default_port=None): """Bind socket to bind ip:port in conf :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6)][0] cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file") sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError("Could not bind to %(bind_addr)s after trying 30 seconds") % {'bind_addr': bind_addr} return sock
def _get_socket(host, port, backlog): info = socket.getaddrinfo( host, port, socket.AF_UNSPEC, socket.SOCK_STREAM )[0] family = info[0] bind_addr = info[-1] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=backlog, family=family) if sslutils.is_enabled(CONF): sock = sslutils.wrap(CONF, sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise if not sock: raise RuntimeError(_( "Could not bind to %(host)s:%(port)s " "after trying for 30 seconds") % {'host': host, 'port': port}) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def get_socket(conf, default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _( "When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file" ) ) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(bind_addr)s" "after trying for 30 seconds") % {"bind_addr": bind_addr} ) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, "TCP_KEEPIDLE"): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) return sock
def get_socket(conf): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :returns: a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ try: bind_port = int(conf['bind_port']) except (ValueError, KeyError, TypeError): raise ConfigFilePortError() bind_addr = (conf.get('bind_ip', '0.0.0.0'), bind_port) address_family = [addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6)][0] sock = None bind_timeout = int(conf.get('bind_timeout', 30)) retry_until = time.time() + bind_timeout warn_ssl = False try: keepidle = int(conf.get('keep_idle', 600)) if keepidle <= 0 or keepidle >= 2 ** 15 - 1: raise ValueError() except (ValueError, KeyError, TypeError): raise ConfigFileError() while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), family=address_family) if 'cert_file' in conf: warn_ssl = True sock = ssl.wrap_socket(sock, certfile=conf['cert_file'], keyfile=conf['key_file']) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1) if not sock: raise Exception(_('Could not bind to %(addr)s:%(port)s ' 'after trying for %(timeout)s seconds') % { 'addr': bind_addr[0], 'port': bind_addr[1], 'timeout': bind_timeout}) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, keepidle) if warn_ssl: ssl_warning_message = _('WARNING: SSL should only be enabled for ' 'testing purposes. Use external SSL ' 'termination for a production deployment.') get_logger(conf).warning(ssl_warning_message) print(ssl_warning_message) return sock
def configure(self): for k in ['host', 'port']: if k not in self.checker_conf: raise exc.ConfigurationException( 'Missing field "%s" in configuration' % k) addrinfo = socket.getaddrinfo( self.checker_conf['host'], self.checker_conf['port'], socktype=socket.SOCK_STREAM, flags=socket.AI_NUMERICHOST)[0] self.family, _, _, _, self.addr = addrinfo
def create(self): addrs = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM) family, socktype, proto, canonname, sockaddr = addrs[0] sock = socket.socket(family, socket.SOCK_STREAM) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) with Timeout(self._connect_timeout): sock.connect(sockaddr) return (sock.makefile(), sock)
def create(self): addrs = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM) family, socktype, proto, canonname, sockaddr = addrs[0] sock = socket.socket(family, socket.SOCK_STREAM) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) with Timeout(self._connect_timeout): sock.connect(sockaddr) return (sock.makefile('rwb'), sock)
def ip_on_same_subnet(first, second, prefix): addrinf = socket.getaddrinfo(first, None, 0, socket.SOCK_STREAM)[0] fam = addrinf[0] ip = socket.inet_pton(fam, addrinf[-1][0]) ip = int(codecs.encode(bytes(ip), 'hex'), 16) addrinf = socket.getaddrinfo(second, None, 0, socket.SOCK_STREAM)[0] if fam != addrinf[0]: return False oip = socket.inet_pton(fam, addrinf[-1][0]) oip = int(codecs.encode(bytes(oip), 'hex'), 16) if fam == socket.AF_INET: addrlen = 32 elif fam == socket.AF_INET6: addrlen = 128 else: raise Exception("Unknown address family {0}".format(fam)) mask = 2**prefix - 1 << (addrlen - prefix) return ip & mask == oip & mask
def get_socket(conf, default_port=61005): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :param default_port: port to use if not specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = (conf.get('bind_ip', '0.0.0.0'), int(conf.get('bind_port', default_port))) address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None bind_timeout = int(conf.get('bind_timeout', 30)) so_rcvbuf = conf.get('so_rcvbuf', None) retry_until = time.time() + bind_timeout warn_ssl = False while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), family=address_family) if 'cert_file' in conf: warn_ssl = True sock = ssl.wrap_socket(sock, certfile=conf['cert_file'], keyfile=conf['key_file']) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1) if not sock: raise Exception( _('Could not bind to %s:%s ' 'after trying for %s seconds') % (bind_addr[0], bind_addr[1], bind_timeout)) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) if so_rcvbuf: sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, int(so_rcvbuf)) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) if warn_ssl: ssl_warning_message = _('WARNING: SSL should only be enabled for ' 'testing purposes. Use external SSL ' 'termination for a production deployment.') get_logger(conf).warning(ssl_warning_message) print(ssl_warning_message) return sock
def _find_srvtype(net, net4, srvtype, addresses, xid): """Internal function to find a single service type Helper to do singleton requests to srvtype :param net: Socket active :param srvtype: Service type to do now :param addresses: Pass through of addresses argument from find_targets :return: """ if addresses is not None: for addr in addresses: for saddr in socket.getaddrinfo(addr, 427): if saddr[0] == socket.AF_INET: net4.sendto(data, saddr[4]) elif saddr[0] == socket.AF_INET6: net.sendto(data, saddr[4]) else: data = _generate_request_payload(srvtype, True, xid) net4.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) v6addrs = [] v6hash = _v6mcasthash(srvtype) # do 'interface local' and 'link local' # it shouldn't make sense, but some configurations work with interface # local that do not work with link local v6addrs.append(('ff01::1:' + v6hash, 427, 0, 0)) v6addrs.append(('ff02::1:' + v6hash, 427, 0, 0)) for idx in util.list_interface_indexes(): # IPv6 multicast is by index, so lead with that net.setsockopt(IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, idx) for sa in v6addrs: try: net.sendto(data, sa) except socket.error: # if we hit an interface without ipv6 multicast, # this can cause an error, skip such an interface # case in point, 'lo' pass for i4 in util.list_ips(): if 'broadcast' not in i4: continue addr = i4['addr'] bcast = i4['broadcast'] net4.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(addr)) try: net4.sendto(data, ('239.255.255.253', 427)) except socket.error as se: # On occasion, multicasting may be disabled # tolerate this scenario and move on if se.errno != 101: raise net4.sendto(data, (bcast, 427))
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None # sock = utils.get_test_suite_socket() retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError(_("Could not bind to %(host)s:%(port)s after" " trying for 30 seconds") % {'host': bind_addr[0], 'port': bind_addr[1]}) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def get_socket(conf): """Bind socket to bind ip:port in conf :param conf: Configuration dict to read settings from :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ try: bind_port = int(conf["bind_port"]) except (ValueError, KeyError, TypeError): raise ConfigFilePortError() bind_addr = (conf.get("bind_ip", "0.0.0.0"), bind_port) address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] sock = None bind_timeout = int(conf.get("bind_timeout", 30)) retry_until = time.time() + bind_timeout warn_ssl = False while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(conf.get("backlog", 4096)), family=address_family) if "cert_file" in conf: warn_ssl = True sock = ssl.wrap_socket(sock, certfile=conf["cert_file"], keyfile=conf["key_file"]) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1) if not sock: raise Exception( _("Could not bind to %s:%s " "after trying for %s seconds") % (bind_addr[0], bind_addr[1], bind_timeout) ) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if hasattr(socket, "TCP_KEEPIDLE"): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 600) if warn_ssl: ssl_warning_message = _( "WARNING: SSL should only be enabled for " "testing purposes. Use external SSL " "termination for a production deployment." ) get_logger(conf).warning(ssl_warning_message) print(ssl_warning_message) return sock
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns: a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] use_ssl = CONF.key_file or CONF.cert_file if use_ssl and (not CONF.key_file or not CONF.cert_file): raise RuntimeError( _("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) sock = utils.get_test_suite_socket() retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(host)s:%(port)s after" " trying for 30 seconds") % { 'host': bind_addr[0], 'port': bind_addr[1] }) return sock
def ip_on_same_subnet(first, second, prefix): if first.startswith('::ffff:') and '.' in first: first = first.replace('::ffff:', '') if second.startswith('::ffff:') and '.' in second: second = second.replace('::ffff:', '') addrinf = socket.getaddrinfo(first, None, 0, socket.SOCK_STREAM)[0] fam = addrinf[0] ip = socket.inet_pton(fam, addrinf[-1][0]) ip = int(codecs.encode(bytes(ip), 'hex'), 16) addrinf = socket.getaddrinfo(second, None, 0, socket.SOCK_STREAM)[0] if fam != addrinf[0]: return False txtaddr = addrinf[-1][0].split('%')[0] oip = socket.inet_pton(fam, txtaddr) oip = int(codecs.encode(bytes(oip), 'hex'), 16) if fam == socket.AF_INET: addrlen = 32 elif fam == socket.AF_INET6: addrlen = 128 else: raise Exception("Unknown address family {0}".format(fam)) mask = 2**prefix - 1 << (addrlen - prefix) return ip & mask == oip & mask
def get_socket(conf, default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Chase with a few small changes... :param conf: a cfg.ConfigOpts object :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(conf, default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] conf.register_opts(socket_opts) cert_file = conf.cert_file key_file = conf.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=conf.backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1)
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns: a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] use_ssl = CONF.key_file or CONF.cert_file if use_ssl and (not CONF.key_file or not CONF.cert_file): raise RuntimeError(_("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) sock = utils.get_test_suite_socket() retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError(_("Could not bind to %(host)s:%(port)s after" " trying for 30 seconds") % {'host': bind_addr[0], 'port': bind_addr[1]}) return sock
def _find_service(service, target): net4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) net6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) net6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) if target: addrs = socket.getaddrinfo(target, 1900, 0, socket.SOCK_DGRAM) for addr in addrs: host = addr[4][0] if addr[0] == socket.AF_INET: net4.sendto(smsg.format(host, service), addr[4]) elif addr[0] == socket.AF_INET6: host = '[{0}]'.format(host) net6.sendto(smsg.format(host, service), addr[4]) else: net4.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) for idx in util.list_interface_indexes(): net6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, idx) try: net6.sendto(smsg.format('[{0}]'.format(mcastv6addr), service), (mcastv6addr, 1900, 0, 0)) except socket.error: # ignore interfaces without ipv6 multicast causing error pass for i4 in util.list_ips(): if 'broadcast' not in i4: continue addr = i4['addr'] bcast = i4['broadcast'] net4.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(addr)) net4.sendto(smsg.format(mcastv4addr, service), (mcastv4addr, 1900)) net4.sendto(smsg.format(bcast, service), (bcast, 1900)) # SSDP by spec encourages responses to spread out over a 3 second interval # hence we must be a bit more patient deadline = util.monotonic_time() + 4 r, _, _ = select.select((net4, net6), (), (), 4) peerdata = {} while r: for s in r: (rsp, peer) = s.recvfrom(9000) neighutil.refresh_neigh() _parse_ssdp(peer, rsp, peerdata) timeout = deadline - util.monotonic_time() if timeout < 0: timeout = 0 r, _, _ = select.select((net4, net6), (), (), timeout) for nid in peerdata: yield peerdata[nid]
def __init__(self, args): super(Client, self).__init__() self.args = args if 'stun' in args and args.stun: import stunloop self.stun = stunloop.Stun() # Discover our local address # TODO: Re-do this periodically, in case it changes s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.connect((args.server, int(args.port))) self.addr = s.getsockname()[0] s.close() # Open our main socket, get its port s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('0.0.0.0', 0)) self.port = s.getsockname()[1] self.sock = s # Resolve the server name addrs = socket.getaddrinfo(args.server, int(args.port), socket.AF_INET, socket.SOCK_DGRAM, socket.SOL_UDP, socket.AI_CANONNAME) # Use the first on the list sin = addrs[0][4] hostname = addrs[0][3] sk = _mkey(sin[0], sin[1]) self.servers = { sk: { 'sin': sin, 'name': hostname, 'ts': time.time(), 'stats': { 'sent': 0, 'rcvd': 0, 'ackd': 0, 'rtt': 0, }, }, } self.clients = {}
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns: a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] retry_until = time.time() + 3 sock = None while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=4096, family=address_family) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: print("Could not bind to %(host)s:%(port)s after" " trying for 30 seconds" % {'host': bind_addr[0], 'port': bind_addr[1]}) exit(1) print("get_sock done: %r" % sock) return sock
def __init__(self, name, app, host='0.0.0.0', port=0, protocol=eventlet.wsgi.HttpProtocol, use_ssl=False, backlog=128, max_url_len=URL_LENGTH_LIMIT): """Initialize, but do not start, a WSGI server. :param app: The name of WSGI application. :param app: The WSGI application to serve. :param host: IP address to serve the application. :param port: Port number to server the application. :returns: None :raises: """ eventlet.wsgi.MAX_HEADER_LINE = CONF.max_header_line self._server = None self.name = name self.app = app self._protocol = protocol self._pool = eventlet.greenpool.GreenPool(CONF.pool_size) self._use_ssl = use_ssl self._max_url_len = max_url_len self.client_socket_timeout = CONF.client_socket_timeout or None self._wsgi_logger = WritableLogger(LOG) if backlog < 1: raise ProxyException('The backlog must be more than 1') bind_addr = (host, port) try: info = socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM)[0] family = info[0] bind_addr = info[-1] except Exception: family = socket.AF_INET self._socket = eventlet.listen(bind_addr, family, backlog=backlog) (self.host, self.port) = self._socket.getsockname()[0:2] LOG.info("%(name)s listening on %(host)s:%(port)s" % self.__dict__)
def get_socket(host, port, conf): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param host: Host to bind to :param port: Port to bind to :param conf: Configuration dict to read settings from :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = (host, port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6)][0] backlog = int(conf.get('backlog', 4096)) cert_file = conf.get('cert_file') key_file = conf.get('key_file') use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError(_("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=backlog, family=address_family) if use_ssl: sock = ssl.wrap_socket(sock, certfile=cert_file, keyfile=key_file) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1)
def get_socket(bind_ip='0.0.0.0',default_port=8080,backlog=4096,cert_file=None,key_file=None): bind_addr = (bind_ip,default_port) address_family = [addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6)][0] sock = None retry_until = time.time() + 30 while not sock and time.time() < retry_until: try: sock = listen(bind_addr, backlog=int(backlog), family=address_family) except socket.error, err: if err.args[0] != errno.EADDRINUSE: raise sleep(0.1)
def connect(self): """Connect to the host and port specified in __init__.""" msg = "getaddrinfo returns an empty list" for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: self.sock = socket.socket(af, socktype, proto) if self.debuglevel > 0: print "connect: (%s, %s)" % (self.host, self.port) self.sock.connect(sa) except socket.error, msg: if self.debuglevel > 0: print 'connect fail:', (self.host, self.port) if self.sock: self.sock.close() self.sock = None continue break
def get_port(addr, clientip, sessionid): global vidforwarder if socket.getaddrinfo(clientip, 0)[0][0] == socket.AF_INET: clientip = '::ffff:' + clientip if sessionid not in ipsbysession: ipsbysession[sessionid] = set([]) if clientip not in sessionsbyip: sessionsbyip[clientip] = set([]) sessionsbyip[clientip].add(sessionid) ipsbysession[sessionid].add(clientip) if sessionid not in forwardersbyclient: forwardersbyclient[sessionid] = {} if addr not in forwardersbyclient[sessionid]: newsock = eventlet.listen(('::', 0, 0, 0), family=socket.AF_INET6) forwardersbyclient[sessionid][addr] = newsock sockhandler[newsock] = eventlet.spawn(forward_port, newsock, addr, clientip, sessionid) if not vidforwarder: vidforwarder = eventlet.spawn(forward_video) vidtargetbypeer[clientip] = addr return forwardersbyclient[sessionid][addr].getsockname()[1]
def handle_request(env, start_response): global currtz global keymap global currlocale global currtzvintage configmanager.check_quorum() nodename = env.get('HTTP_CONFLUENT_NODENAME', None) apikey = env.get('HTTP_CONFLUENT_APIKEY', None) if not (nodename and apikey): start_response('401 Unauthorized', []) yield 'Unauthorized' return cfg = configmanager.ConfigManager(None) ea = cfg.get_node_attributes(nodename, ['crypted.selfapikey', 'deployment.apiarmed']) eak = ea.get(nodename, {}).get('crypted.selfapikey', {}).get('hashvalue', None) if not eak: start_response('401 Unauthorized', []) yield 'Unauthorized' return salt = '$'.join(eak.split('$', 3)[:-1]) + '$' if crypt.crypt(apikey, salt) != eak: start_response('401 Unauthorized', []) yield 'Unauthorized' return if ea.get(nodename, {}).get('deployment.apiarmed', {}).get('value', None) == 'once': cfg.set_node_attributes({nodename: {'deployment.apiarmed': ''}}) retype = env.get('HTTP_ACCEPT', 'application/yaml') isgeneric = False if retype == '*/*': isgeneric = True retype = 'application/yaml' if retype == 'application/yaml': dumper = yamldump elif retype == 'application/json': dumper = json.dumps else: start_response('406 Not supported', []) yield 'Unsupported content type in ACCEPT: ' + retype return operation = env['REQUEST_METHOD'] if operation not in ('HEAD', 'GET') and 'CONTENT_LENGTH' in env and int( env['CONTENT_LENGTH']) > 0: reqbody = env['wsgi.input'].read(int(env['CONTENT_LENGTH'])) if env['PATH_INFO'] == '/self/bmcconfig': hmattr = cfg.get_node_attributes(nodename, 'hardwaremanagement.*') hmattr = hmattr.get(nodename, {}) res = {} port = hmattr.get('hardwaremanagement.port', {}).get('value', None) if port is not None: res['bmcport'] = port vlan = hmattr.get('hardwaremanagement.vlan', {}).get('value', None) if vlan is not None: res['bmcvlan'] = vlan bmcaddr = hmattr.get('hardwaremanagement.manager', {}).get('value', None) bmcaddr = socket.getaddrinfo(bmcaddr, 0)[0] bmcaddr = bmcaddr[-1][0] if '.' in bmcaddr: # ipv4 is allowed netconfig = netutil.get_nic_config(cfg, nodename, ip=bmcaddr) res['bmcipv4'] = bmcaddr res['prefixv4'] = netconfig['prefix'] res['bmcgw'] = netconfig.get('ipv4_gateway', None) # credential security results in user/password having to be deferred start_response('200 OK', (('Content-Type', retype), )) yield dumper(res) elif env['PATH_INFO'] == '/self/deploycfg': if 'HTTP_CONFLUENT_MGTIFACE' in env: ncfg = netutil.get_nic_config(cfg, nodename, ifidx=env['HTTP_CONFLUENT_MGTIFACE']) else: myip = env.get('HTTP_X_FORWARDED_HOST', None) if ']' in myip: myip = myip.split(']', 1)[0] else: myip = myip.split(':', 1)[0] myip = myip.replace('[', '').replace(']', '') ncfg = netutil.get_nic_config(cfg, nodename, serverip=myip) if ncfg['prefix']: ncfg['ipv4_netmask'] = netutil.cidr_to_mask(ncfg['prefix']) if ncfg['ipv4_method'] == 'firmwaredhcp': ncfg['ipv4_method'] = 'static' deployinfo = cfg.get_node_attributes( nodename, ('deployment.*', 'console.method', 'crypted.*', 'dns.*', 'ntp.*')) deployinfo = deployinfo.get(nodename, {}) profile = deployinfo.get('deployment.pendingprofile', {}).get('value', '') ncfg['encryptboot'] = deployinfo.get('deployment.encryptboot', {}).get('value', None) if ncfg['encryptboot'] in ('', 'none'): ncfg['encryptboot'] = None ncfg['profile'] = profile protocol = deployinfo.get('deployment.useinsecureprotocols', {}).get('value', 'never') ncfg['textconsole'] = bool( deployinfo.get('console.method', {}).get('value', None)) if protocol == 'always': ncfg['protocol'] = 'http' else: ncfg['protocol'] = 'https' ncfg['rootpassword'] = deployinfo.get('crypted.rootpassword', {}).get('hashvalue', None) ncfg['grubpassword'] = deployinfo.get('crypted.grubpassword', {}).get('grubhashvalue', None) if currtzvintage and currtzvintage > (time.time() - 30.0): ncfg['timezone'] = currtz else: langinfo = subprocess.check_output(['localectl', 'status']).split(b'\n') for line in langinfo: line = line.strip() if line.startswith(b'System Locale:'): ccurrlocale = line.split(b'=')[-1] if not ccurrlocale: continue if not isinstance(ccurrlocale, str): ccurrlocale = ccurrlocale.decode('utf8') if ccurrlocale == 'n/a': continue currlocale = ccurrlocale elif line.startswith(b'VC Keymap:'): ckeymap = line.split(b':')[-1] ckeymap = ckeymap.strip() if not ckeymap: continue if not isinstance(ckeymap, str): ckeymap = ckeymap.decode('utf8') if ckeymap == 'n/a': continue keymap = ckeymap tdc = subprocess.check_output(['timedatectl']).split(b'\n') for ent in tdc: ent = ent.strip() if ent.startswith(b'Time zone:'): currtz = ent.split(b': ', 1)[1].split(b'(', 1)[0].strip() if not isinstance(currtz, str): currtz = currtz.decode('utf8') currtzvintage = time.time() ncfg['timezone'] = currtz break ncfg['locale'] = currlocale ncfg['keymap'] = keymap ncfg['nameservers'] = [] for dns in deployinfo.get('dns.servers', {}).get('value', '').split(','): ncfg['nameservers'].append(dns) ntpsrvs = deployinfo.get('ntp.servers', {}).get('value', '') if ntpsrvs: ntpsrvs = ntpsrvs.split(',') if ntpsrvs: ncfg['ntpservers'] = [] for ntpsrv in ntpsrvs: ncfg['ntpservers'].append(ntpsrv) dnsdomain = deployinfo.get('dns.domain', {}).get('value', None) ncfg['dnsdomain'] = dnsdomain start_response('200 OK', (('Content-Type', retype), )) yield dumper(ncfg) elif env['PATH_INFO'] == '/self/sshcert' and reqbody: if not sshutil.ca_exists(): start_response('500 Unconfigured', ()) yield 'CA is not configured on this system (run ...)' return pals = get_extra_names(nodename, cfg) cert = sshutil.sign_host_key(reqbody, nodename, pals) start_response('200 OK', (('Content-Type', 'text/plain'), )) yield cert elif env['PATH_INFO'] == '/self/nodelist': nodes, _ = get_cluster_list(nodename, cfg) if isgeneric: start_response('200 OK', (('Content-Type', 'text/plain'), )) for node in util.natural_sort(nodes): yield node + '\n' else: start_response('200 OK', (('Content-Type', retype), )) yield dumper(sorted(nodes)) elif env['PATH_INFO'] == '/self/remoteconfigbmc' and reqbody: try: reqbody = yaml.safe_load(reqbody) except Exception: reqbody = None cfgmod = reqbody.get('configmod', 'unspecified') if cfgmod == 'xcc': xcc.remote_nodecfg(nodename, cfg) elif cfgmod == 'tsm': tsm.remote_nodecfg(nodename, cfg) else: start_response('500 unsupported configmod', ()) yield 'Unsupported configmod "{}"'.format(cfgmod) start_response('200 Ok', ()) yield 'complete' elif env['PATH_INFO'] == '/self/updatestatus' and reqbody: update = yaml.safe_load(reqbody) if update['status'] == 'staged': targattr = 'deployment.stagedprofile' elif update['status'] == 'complete': targattr = 'deployment.profile' else: raise Exception('Unknown update status request') currattr = cfg.get_node_attributes(nodename, 'deployment.*').get(nodename, {}) pending = None if targattr == 'deployment.profile': pending = currattr.get('deployment.stagedprofile', {}).get('value', '') if not pending: pending = currattr.get('deployment.pendingprofile', {}).get('value', '') updates = {} if pending: updates['deployment.pendingprofile'] = {'value': ''} if targattr == 'deployment.profile': updates['deployment.stagedprofile'] = {'value': ''} currprof = currattr.get(targattr, {}).get('value', '') if currprof != pending: updates[targattr] = {'value': pending} cfg.set_node_attributes({nodename: updates}) start_response('200 OK', (('Content-Type', 'text/plain'), )) yield 'OK' else: start_response('500 Error', (('Content-Type', 'text/plain'), )) yield 'No pending profile detected, unable to accept status update' elif env['PATH_INFO'] == '/self/saveapikey' and reqbody: if not isinstance(reqbody, str): reqbody = reqbody.decode('utf8') cfg.set_node_attributes( {nodename: { 'deployment.sealedapikey': { 'value': reqbody } }}) start_response('200 OK', ()) yield '' elif env['PATH_INFO'].startswith( '/self/remoteconfig/') and 'POST' == operation: scriptcat = env['PATH_INFO'].replace('/self/remoteconfig/', '') slist, profile = get_scriptlist( scriptcat, cfg, nodename, '/var/lib/confluent/public/os/{0}/ansible/{1}') playlist = [] dirname = '/var/lib/confluent/public/os/{0}/ansible/{1}/'.format( profile, scriptcat) if not os.path.isdir(dirname): dirname = '/var/lib/confluent/public/os/{0}/ansible/{1}.d/'.format( profile, scriptcat) for filename in slist: if filename.endswith('.yaml') or filename.endswith('.yml'): playlist.append(os.path.join(dirname, filename)) if playlist: runansible.run_playbooks(playlist, [nodename]) start_response('202 Queued', ()) yield '' else: start_response('200 OK', ()) yield '' return elif env['PATH_INFO'].startswith('/self/remotesyncfiles'): if 'POST' == operation: result = syncfiles.start_syncfiles(nodename, cfg, json.loads(reqbody)) start_response(result, ()) yield '' return if 'GET' == operation: status, output = syncfiles.get_syncresult(nodename) start_response(status, ()) yield output return elif env['PATH_INFO'].startswith('/self/remoteconfig/status'): rst = runansible.running_status.get(nodename, None) if not rst: start_response('204 Not Running', (('Content-Length', '0'), )) yield '' return start_response('200 OK', ()) if rst.complete: del runansible.running_status[nodename] yield rst.dump_text() return elif env['PATH_INFO'].startswith('/self/scriptlist/'): scriptcat = env['PATH_INFO'].replace('/self/scriptlist/', '') slist, _ = get_scriptlist( scriptcat, cfg, nodename, '/var/lib/confluent/public/os/{0}/scripts/{1}') if slist: start_response('200 OK', (('Content-Type', 'application/yaml'), )) yield yaml.safe_dump(util.natural_sort(slist), default_flow_style=False) else: start_response('200 OK', ()) yield '' else: start_response('404 Not Found', ()) yield 'Not found'
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = CONF.cert_file key_file = CONF.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError(_("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) def wrap_ssl(sock): utils.validate_key_cert(key_file, cert_file) ssl_kwargs = { 'server_side': True, 'certfile': cert_file, 'keyfile': key_file, 'cert_reqs': ssl.CERT_NONE, } if CONF.ca_file: ssl_kwargs['ca_certs'] = CONF.ca_file ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs) sock = utils.get_test_suite_socket() retry_until = time.time() + 30 if sock and use_ssl: sock = wrap_ssl(sock) while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) if use_ssl: sock = wrap_ssl(sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError(_("Could not bind to %s:%s after trying for 30 " "seconds") % bind_addr) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... """ bind_addr = get_bind_addr(default_port) address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = CONF.cert_file key_file = CONF.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file") def wrap_ssl(sock): utils.validate_key_cert(key_file, cert_file) ssl_kwargs = { 'server_side': True, 'certfile': cert_file, 'keyfile': key_file, 'cert_reqs': ssl.CERT_NONE, } if CONF.ca_file: ssl_kwargs['ca_certs'] = CONF.ca_file ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs) sock = utils.get_test_suite_socket() retry_until = time.time() + 30 if sock and use_ssl: sock = wrap_ssl(sock) while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) if use_ssl: sock = wrap_ssl(sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None, serverip=None): """Fetch network configuration parameters for a nic For a given node and interface, find and retrieve the pertinent network configuration data. The desired configuration can be searched either by ip or by mac. :param configmanager: The relevant confluent.config.ConfigManager instance. :param node: The name of the node :param ip: An IP address on the intended subnet :param mac: The mac address of the interface :param ifidx: The local index relevant to the network. :returns: A dict of parameters, 'ipv4_gateway', .... """ # ip parameter *could* be the result of recvmsg with cmsg to tell # pxe *our* ip address, or it could be the desired ip address #TODO(jjohnson2): ip address, prefix length, mac address, # join a bond/bridge, vlan configs, etc. # also other nic criteria, physical location, driver and index... nodenetattribs = configmanager.get_node_attributes(node, 'net*').get(node, {}) cfgbyname = {} for attrib in nodenetattribs: segs = attrib.split('.') if len(segs) == 2: name = None else: name = segs[1] if name not in cfgbyname: cfgbyname[name] = {} cfgbyname[name][segs[-1]] = nodenetattribs[attrib].get('value', None) cfgdata = { 'ipv4_gateway': None, 'ipv4_address': None, 'ipv4_method': None, 'prefix': None, } nets = None needsvrip = False if ifidx is not None: dhcprequested = False nets = list(_iftonets(ifidx)) if not nets: cfgdata['ipv4_broken'] = True if serverip is not None: needsvrip = True dhcprequested = False nets = list(myiptonets(serverip)) if nets is not None: candgws = [] candsrvs = [] for net in nets: net, prefix, svrip = net candsrvs.append(svrip) cfgdata['deploy_server'] = svrip for candidate in cfgbyname: if cfgbyname[candidate].get('ipv4_method', None) == 'dhcp': dhcprequested = True continue candip = cfgbyname[candidate].get('ipv4_address', None) if candip and '/' in candip: candip, candprefix = candip.split('/') if int(candprefix) != prefix: continue candgw = cfgbyname[candidate].get('ipv4_gateway', None) if candip: if ip_on_same_subnet(net, candip, prefix): cfgdata['ipv4_address'] = candip cfgdata['ipv4_method'] = 'static' cfgdata['ipv4_gateway'] = cfgbyname[candidate].get( 'ipv4_gateway', None) cfgdata['prefix'] = prefix return cfgdata elif candgw: if ip_on_same_subnet(net, candgw, prefix): candgws.append(candgw) if dhcprequested: return cfgdata ipbynodename = None try: ipbynodename = socket.getaddrinfo(node, 0, socket.AF_INET, socket.SOCK_DGRAM)[0][-1][0] except Exception: return cfgdata for net in nets: net, prefix, svrip = net if ip_on_same_subnet(net, ipbynodename, prefix): cfgdata['matchesnodename'] = True cfgdata['ipv4_address'] = ipbynodename cfgdata['ipv4_method'] = 'static' cfgdata['prefix'] = prefix break for svr in candsrvs: if ip_on_same_subnet(svr, ipbynodename, prefix): cfgdata['deploy_server'] = svr break for gw in candgws: if ip_on_same_subnet(gw, ipbynodename, prefix): cfgdata['ipv4_gateway'] = gw break return cfgdata if ip is not None: prefixlen = get_prefix_len_for_ip(ip) cfgdata['prefix'] = prefixlen for setting in nodenetattribs: if 'ipv4_gateway' not in setting: continue gw = nodenetattribs[setting].get('value', None) if gw is None or not gw: continue if ip_on_same_subnet(ip, gw, prefixlen): cfgdata['ipv4_gateway'] = gw break return cfgdata
def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo( bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = CONF.cert_file key_file = CONF.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError( _("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) def wrap_ssl(sock): utils.validate_key_cert(key_file, cert_file) ssl_kwargs = { 'server_side': True, 'certfile': cert_file, 'keyfile': key_file, 'cert_reqs': ssl.CERT_NONE, } if CONF.ca_file: ssl_kwargs['ca_certs'] = CONF.ca_file ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs) sock = utils.get_test_suite_socket() retry_until = time.time() + 30 if sock and use_ssl: sock = wrap_ssl(sock) while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) if use_ssl: sock = wrap_ssl(sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError( _("Could not bind to %(host)s:%(port)s after" " trying for 30 seconds") % { 'host': bind_addr[0], 'port': bind_addr[1] }) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock
def test_getaddrinfo_ipv6_scope(): greendns.is_ipv6_addr('::1%2') if not socket.has_ipv6: return socket.getaddrinfo('::1%2', 80, socket.AF_INET6)
def _find_service(service, target): net4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) net6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) net6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) if target: addrs = socket.getaddrinfo(target, 1900, 0, socket.SOCK_DGRAM) for addr in addrs: host = addr[4][0] if addr[0] == socket.AF_INET: msg = smsg.format(host, service) if not isinstance(msg, bytes): msg = msg.encode('utf8') net4.sendto(msg, addr[4]) elif addr[0] == socket.AF_INET6: host = '[{0}]'.format(host) msg = smsg.format(host, service) if not isinstance(msg, bytes): msg = msg.encode('utf8') net6.sendto(msg, addr[4]) else: net4.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) for idx in util.list_interface_indexes(): net6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, idx) try: msg = smsg.format('[{0}]'.format(mcastv6addr), service) if not isinstance(msg, bytes): msg = msg.encode('utf8') net6.sendto(msg, (mcastv6addr, 1900, 0, 0)) except socket.error: # ignore interfaces without ipv6 multicast causing error pass for i4 in util.list_ips(): if 'broadcast' not in i4: continue addr = i4['addr'] bcast = i4['broadcast'] net4.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(addr)) msg = smsg.format(mcastv4addr, service) if not isinstance(msg, bytes): msg = msg.encode('utf8') net4.sendto(msg, (mcastv4addr, 1900)) msg = smsg.format(bcast, service) if not isinstance(msg, bytes): msg = msg.encode('utf8') net4.sendto(msg, (bcast, 1900)) # SSDP by spec encourages responses to spread out over a 3 second interval # hence we must be a bit more patient deadline = util.monotonic_time() + 4 r, _, _ = select.select((net4, net6), (), (), 4) peerdata = {} while r: for s in r: (rsp, peer) = s.recvfrom(9000) neighutil.refresh_neigh() _parse_ssdp(peer, rsp, peerdata) timeout = deadline - util.monotonic_time() if timeout < 0: timeout = 0 r, _, _ = select.select((net4, net6), (), (), timeout) querypool = gp.GreenPool() pooltargs = [] for nid in peerdata: for url in peerdata[nid].get('urls', ()): if url.endswith('/desc.tmpl'): pooltargs.append((url, peerdata[nid])) for pi in querypool.imap(check_cpstorage, pooltargs): if pi is not None: yield pi