def connect(self, host, port):
family, socktype, proto, _, sockaddr = socket.getaddrinfo(host, port, self.family, self.socktype)[0]
s = socket.socket(family, socktype, proto)
s.settimeout(self.timeout)
s.connect(sockaddr)
if self.nodelay:
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
if self.keepalive:
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
# Linux specific: after 1 idle minutes, start sending keepalives every 5 minutes.
# Drop connection after 10 failed keepalives
if hasattr(socket, "TCP_KEEPIDLE") and hasattr(socket, "TCP_KEEPINTVL") and hasattr(socket, "TCP_KEEPCNT"):
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1 * 60)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 5 * 60)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 10)
self.sock=s
return s
python类TCP_KEEPCNT的实例源码
def connect(self, host, port):
s = socks.socksocket()
s.setproxy(proxy_type=socks.PROXY_TYPES[self.proxy_type], addr=self.proxy_addr, port=self.proxy_port, rdns=True, username=self.proxy_username, password=self.proxy_password)
s.settimeout(self.timeout)
s.connect((host,port))
if self.nodelay:
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
if self.keepalive:
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
# Linux specific: after 10 idle minutes, start sending keepalives every 5 minutes.
# Drop connection after 10 failed keepalives
if hasattr(socket, "TCP_KEEPIDLE") and hasattr(socket, "TCP_KEEPINTVL") and hasattr(socket, "TCP_KEEPCNT"):
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 10 * 60)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 5 * 60)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 10)
self.sock=s
return s
def __init__(self, **kwargs):
socket_options = kwargs.pop('socket_options',
SocketOptionsAdapter.default_options)
idle = kwargs.pop('idle', 60)
interval = kwargs.pop('interval', 20)
count = kwargs.pop('count', 5)
socket_options = socket_options + [
(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval),
(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, count),
]
# NOTE(Ian): Apparently OSX does not have this constant defined, so we
# set it conditionally.
if getattr(socket, 'TCP_KEEPIDLE', None) is not None:
socket_options += [(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, idle)]
super(TCPKeepAliveAdapter, self).__init__(
socket_options=socket_options, **kwargs
)
def __init__(self, **kwargs):
socket_options = kwargs.pop('socket_options',
SocketOptionsAdapter.default_options)
idle = kwargs.pop('idle', 60)
interval = kwargs.pop('interval', 20)
count = kwargs.pop('count', 5)
socket_options = socket_options + [
(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval),
(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, count),
]
# NOTE(Ian): Apparently OSX does not have this constant defined, so we
# set it conditionally.
if getattr(socket, 'TCP_KEEPIDLE', None) is not None:
socket_options += [(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, idle)]
super(TCPKeepAliveAdapter, self).__init__(
socket_options=socket_options, **kwargs
)
def __init__(self, ip, port, callbacks_info, max_client = 50):
assert (ip != '')
skt = socket.socket()
# Avoid 'Address already in use' error when trying to lanch server
# again right after shutting it down.
skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
skt.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if sys.platform == 'linux':
skt.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60)
skt.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 4)
skt.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 15)
skt.bind((ip, port))
skt.listen(max_client)
self.connections = []
self.clients = {}
self.msg_handler = MessageHandler(skt, callbacks_info,
mh_creator = self.client_mh_creator,
mh_remover = self.client_mh_remover)
self.thread = TaskThread(name='server_recv_loop')
self.thread.daemon = True
self.evt_break = threading.Event()
self.evt_break.clear()
def __init__(self, **kwargs):
socket_options = kwargs.pop('socket_options',
SocketOptionsAdapter.default_options)
idle = kwargs.pop('idle', 60)
interval = kwargs.pop('interval', 20)
count = kwargs.pop('count', 5)
socket_options = socket_options + [
(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval),
(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, count),
]
# NOTE(Ian): Apparently OSX does not have this constant defined, so we
# set it conditionally.
if getattr(socket, 'TCP_KEEPIDLE', None) is not None:
socket_options += [(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, idle)]
super(TCPKeepAliveAdapter, self).__init__(
socket_options=socket_options, **kwargs
)
def _activate_keepalive(self, s, after_idle_sec=30, interval_sec=10,
max_fails=5):
"""Set TCP keepalive on an open socket.
It activates after 30 second (after_idle_sec) of idleness,
then sends a keepalive ping once every 10 seconds (interval_sec),
and closes the connection after 5 failed ping (max_fails).
"""
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
def set_keepalive(self):
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 5)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 5)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
def set_keepalive(self):
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 5)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 5)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
def test_set_tcp_keepalive(self):
mock_sock = mock.Mock()
netutils.set_tcp_keepalive(mock_sock, True, 100, 10, 5)
calls = [
mock.call.setsockopt(socket.SOL_SOCKET,
socket.SO_KEEPALIVE, True),
]
if hasattr(socket, 'TCP_KEEPIDLE'):
calls += [
mock.call.setsockopt(socket.IPPROTO_TCP,
socket.TCP_KEEPIDLE, 100)
]
if hasattr(socket, 'TCP_KEEPINTVL'):
calls += [
mock.call.setsockopt(socket.IPPROTO_TCP,
socket.TCP_KEEPINTVL, 10),
]
if hasattr(socket, 'TCP_KEEPCNT'):
calls += [
mock.call.setsockopt(socket.IPPROTO_TCP,
socket.TCP_KEEPCNT, 5)
]
mock_sock.assert_has_calls(calls)
mock_sock.reset_mock()
netutils.set_tcp_keepalive(mock_sock, False)
self.assertEqual(1, len(mock_sock.mock_calls))
def set_socket(s, keep_alive=False):
# TCP socket keep alive
if keep_alive and sys.platform == "linux":
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 30)
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 5)
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 3)
def test_socket_set_keepalive_options(self):
keepcnt = 12
keepidle = 34
keepintvl = 56
server = self._get_server(daemon=False, ssl_only=0, idle_timeout=1)
sock = server.socket('localhost',
tcp_keepcnt=keepcnt,
tcp_keepidle=keepidle,
tcp_keepintvl=keepintvl)
self.assertEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPCNT), keepcnt)
self.assertEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPIDLE), keepidle)
self.assertEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPINTVL), keepintvl)
sock = server.socket('localhost',
tcp_keepalive=False,
tcp_keepcnt=keepcnt,
tcp_keepidle=keepidle,
tcp_keepintvl=keepintvl)
self.assertNotEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPCNT), keepcnt)
self.assertNotEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPIDLE), keepidle)
self.assertNotEqual(sock.getsockopt(socket.SOL_TCP,
socket.TCP_KEEPINTVL), keepintvl)
def set_keepalive(self,_sock, after_idle_sec=5, interval_sec=3, max_fails=60):
"""Set TCP keepalive on an open socket.--new add
It activates after 1 second (after_idle_sec) of idleness,
then sends a keepalive ping once every 3 seconds (interval_sec),
and closes the connection after 60 failed ping (max_fails), or 180 seconds
"""
_sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
def redis_init_conn(cls):
"""
* Added TCP Keep-alive support by passing use the socket_keepalive=True
option. Finer grain control can be achieved using the
socket_keepalive_options option which expects a dictionary with any of
the keys (socket.TCP_KEEPIDLE, socket.TCP_KEEPCNT, socket.TCP_KEEPINTVL)
and integers for values. Thanks Yossi Gottlieb.
TCP_KEEPDILE ?????????????????????keepalive?????????
TCP_KEEPINTVL ??????????????????
TCP_KEEPCNT ??????????????????
"""
import socket
_r = redis.StrictRedis(host=cls.config.get('redis_host', '127.0.0.1'), port=cls.config.get('redis_port', 6379),
db=cls.config.get('redis_dbid', 0), decode_responses=True, socket_timeout=5,
socket_connect_timeout=5, socket_keepalive=True,
socket_keepalive_options={socket.TCP_KEEPIDLE: 2, socket.TCP_KEEPINTVL: 5,
socket.TCP_KEEPCNT: 10},
retry_on_timeout=True)
try:
_r.ping()
except redis.exceptions.ResponseError as e:
logger.warn(e.message)
_r = redis.StrictRedis(
host=cls.config.get('redis_host', '127.0.0.1'), port=cls.config.get('redis_port', 6379),
db=cls.config.get('redis_dbid', 0), password=cls.config.get('redis_password', ''),
decode_responses=True, socket_timeout=5, socket_connect_timeout=5, socket_keepalive=True,
socket_keepalive_options={socket.TCP_KEEPIDLE: 2, socket.TCP_KEEPINTVL: 5,
socket.TCP_KEEPCNT: 10},
retry_on_timeout=True)
_r.client_setname(ji.Common.get_hostname())
return _r
def _set_keep_alive(self):
stream_socket = self._stream.socket
stream_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if platform.system().lower() == 'linux':
stream_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 30)
stream_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 5)
stream_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 5)
def _set_keep_alive(self):
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if platform.system().lower() == 'linux':
self._socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 30)
self._socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 5)
self._socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 5)
def _set_keep_alive(self):
if not self._config.ENABLE_KEEP_ALIVE:
return
stream_socket = self._stream.socket
stream_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if platform.system().lower() == 'linux':
stream_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, self._config.KEEP_ALIVE_OPT['timeout'])
stream_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, self._config.KEEP_ALIVE_OPT['interval'])
stream_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, self._config.KEEP_ALIVE_OPT['count'])
def bindServer(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if platform.system() != 'Darwin':
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # After 1 second, start KEEPALIVE
self.server.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1) # TCP Idle true
self.server.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 5) # 5 seconds in between keepalive pings
self.server.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5) # 5 max fails
# Bind the socket to the port
while True:
try:
self.server.bind(('', APP_SERVER_PORT))
except:
logger.log("[app]: Can't bind, address in use. Retrying in 1 second.")
time.sleep(1.0)
else:
break
logger.log("[app]: Ready for connections from app.")
# Listen for incoming connections
self.server.listen(0)
# establishes a connection to a Solo app
def set_keepalive(sock, after_idle_sec=1, interval_sec=3, max_fails=5):
"""Set TCP keepalive on an open socket.
It activates after 1 second (after_idle_sec) of idleness,
then sends a keepalive ping once every 3 seconds (interval_sec),
and closes the connection after 5 failed ping (max_fails), or 15 seconds
"""
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
def set_keepalive(sock, after_idle_sec=1, interval_sec=3, max_fails=5):
"""Set TCP keepalive on an open socket.
It activates after 1 second (after_idle_sec) of idleness,
then sends a keepalive ping once every 3 seconds (interval_sec),
and closes the connection after 5 failed ping (max_fails), or 15 seconds
"""
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
def handle( self, source, address ):
global currentEndpoints
try:
if 0 == len( currentEndpoints ): return
print( "Connection from %s" % str( address ) )
try:
source.setsockopt( socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1 )
source.setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 5 )
source.setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10 )
source.setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2 )
except:
print( "Failed to set keepalive on source connection" )
try:
dest = create_connection( random.sample( currentEndpoints, 1 )[ 0 ] )
except:
print( "Failed to connect to EndpointProcessor" )
else:
try:
try:
dest.setsockopt( socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1 )
dest.setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 5 )
dest.setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10 )
dest.setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2 )
except:
print( "Failed to set keepalive on dest connection" )
# Send a small connection header that contains the original
# source of the connection.
connectionHeaders = msgpack.packb( address )
dest.sendall( struct.pack( '!I', len( connectionHeaders ) ) )
dest.sendall( connectionHeaders )
gevent.joinall( ( gevent.spawn( forward, source, dest, address, self ),
gevent.spawn( forward, dest, source, address, self ) ) )
finally:
dest.close()
finally:
source.close()
def handle_connect(self):
"""Server socket gets a connection"""
# accept a connection in any case, close connection
# below if already busy
connection, addr = self.server_socket.accept()
if self.socket is None:
self.socket = connection
# More quickly detect bad clients who quit without closing the
# connection: After 1 second of idle, start sending TCP keep-alive
# packets every 1 second. If 3 consecutive keep-alive packets
# fail, assume the client is gone and close the connection.
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 3)
self.socket.setblocking(0)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
if self.log is not None:
self.log.warning('{}: Connected by {}:{}'.format(self.device, addr[0], addr[1]))
self.serial.rts = True
self.serial.dtr = True
if self.log is not None:
self.rfc2217 = serial.rfc2217.PortManager(self.serial, self, logger=log.getChild(self.device))
else:
self.rfc2217 = serial.rfc2217.PortManager(self.serial, self)
else:
# reject connection if there is already one
connection.close()
if self.log is not None:
self.log.warning('{}: Rejecting connect from {}:{}'.format(self.device, addr[0], addr[1]))
def socket(host, port=None, connect=False, prefer_ipv6=False,
unix_socket=None, use_ssl=False, tcp_keepalive=True,
tcp_keepcnt=None, tcp_keepidle=None, tcp_keepintvl=None):
""" Resolve a host (and optional port) to an IPv4 or IPv6
address. Create a socket. Bind to it if listen is set,
otherwise connect to it. Return the socket.
"""
flags = 0
if host == '':
host = None
if connect and not (port or unix_socket):
raise Exception("Connect mode requires a port")
if use_ssl and not ssl:
raise Exception("SSL socket requested but Python SSL module not loaded.");
if not connect and use_ssl:
raise Exception("SSL only supported in connect mode (for now)")
if not connect:
flags = flags | socket.AI_PASSIVE
if not unix_socket:
addrs = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM,
socket.IPPROTO_TCP, flags)
if not addrs:
raise Exception("Could not resolve host '%s'" % host)
addrs.sort(key=lambda x: x[0])
if prefer_ipv6:
addrs.reverse()
sock = socket.socket(addrs[0][0], addrs[0][1])
if tcp_keepalive:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if tcp_keepcnt:
sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT,
tcp_keepcnt)
if tcp_keepidle:
sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE,
tcp_keepidle)
if tcp_keepintvl:
sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL,
tcp_keepintvl)
if connect:
sock.connect(addrs[0][4])
if use_ssl:
sock = ssl.wrap_socket(sock)
else:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addrs[0][4])
sock.listen(100)
else:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(unix_socket)
return sock
def set_tcp_keepalive(sock, tcp_keepalive=True,
tcp_keepidle=None,
tcp_keepalive_interval=None,
tcp_keepalive_count=None):
"""Set values for tcp keepalive parameters
This function configures tcp keepalive parameters if users wish to do
so.
:param tcp_keepalive: Boolean, turn on or off tcp_keepalive. If users are
not sure, this should be True, and default values will be used.
:param tcp_keepidle: time to wait before starting to send keepalive probes
:param tcp_keepalive_interval: time between successive probes, once the
initial wait time is over
:param tcp_keepalive_count: number of probes to send before the connection
is killed
"""
# NOTE(praneshp): Despite keepalive being a tcp concept, the level is
# still SOL_SOCKET. This is a quirk.
if isinstance(tcp_keepalive, bool):
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, tcp_keepalive)
else:
raise TypeError("tcp_keepalive must be a boolean")
if not tcp_keepalive:
return
# These options aren't available in the OS X version of eventlet,
# Idle + Count * Interval effectively gives you the total timeout.
if tcp_keepidle is not None:
if hasattr(socket, 'TCP_KEEPIDLE'):
sock.setsockopt(socket.IPPROTO_TCP,
socket.TCP_KEEPIDLE,
tcp_keepidle)
else:
LOG.warning(_LW('tcp_keepidle not available on your system'))
if tcp_keepalive_interval is not None:
if hasattr(socket, 'TCP_KEEPINTVL'):
sock.setsockopt(socket.IPPROTO_TCP,
socket.TCP_KEEPINTVL,
tcp_keepalive_interval)
else:
LOG.warning(_LW('tcp_keepintvl not available on your system'))
if tcp_keepalive_count is not None:
if hasattr(socket, 'TCP_KEEPCNT'):
sock.setsockopt(socket.IPPROTO_TCP,
socket.TCP_KEEPCNT,
tcp_keepalive_count)
else:
LOG.warning(_LW('tcp_keepcnt not available on your system'))
def socket(host, port=None, connect=False, prefer_ipv6=False,
unix_socket=None, use_ssl=False, tcp_keepalive=True,
tcp_keepcnt=None, tcp_keepidle=None, tcp_keepintvl=None):
""" Resolve a host (and optional port) to an IPv4 or IPv6
address. Create a socket. Bind to it if listen is set,
otherwise connect to it. Return the socket.
"""
flags = 0
if host == '':
host = None
if connect and not (port or unix_socket):
raise Exception("Connect mode requires a port")
if use_ssl and not ssl:
raise Exception("SSL socket requested but Python SSL module not loaded.");
if not connect and use_ssl:
raise Exception("SSL only supported in connect mode (for now)")
if not connect:
flags = flags | socket.AI_PASSIVE
if not unix_socket:
addrs = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM,
socket.IPPROTO_TCP, flags)
if not addrs:
raise Exception("Could not resolve host '%s'" % host)
addrs.sort(key=lambda x: x[0])
if prefer_ipv6:
addrs.reverse()
sock = socket.socket(addrs[0][0], addrs[0][1])
if tcp_keepalive:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if tcp_keepcnt:
sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT,
tcp_keepcnt)
if tcp_keepidle:
sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE,
tcp_keepidle)
if tcp_keepintvl:
sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL,
tcp_keepintvl)
if connect:
sock.connect(addrs[0][4])
if use_ssl:
sock = ssl.wrap_socket(sock)
else:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addrs[0][4])
sock.listen(100)
else:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(unix_socket)
return sock