1import os
2import sys
3
4__import__('eventlet.green._socket_nodns')
5__socket = sys.modules['eventlet.green._socket_nodns']
6
7__all__ = __socket.__all__
8__patched__ = __socket.__patched__ + [
9    'create_connection',
10    'getaddrinfo',
11    'gethostbyname',
12    'gethostbyname_ex',
13    'getnameinfo',
14]
15
16from eventlet.patcher import slurp_properties
17slurp_properties(__socket, globals(), srckeys=dir(__socket))
18
19
20if os.environ.get("EVENTLET_NO_GREENDNS", '').lower() != 'yes':
21    from eventlet.support import greendns
22    gethostbyname = greendns.gethostbyname
23    getaddrinfo = greendns.getaddrinfo
24    gethostbyname_ex = greendns.gethostbyname_ex
25    getnameinfo = greendns.getnameinfo
26    del greendns
27
28
29def create_connection(address,
30                      timeout=_GLOBAL_DEFAULT_TIMEOUT,
31                      source_address=None):
32    """Connect to *address* and return the socket object.
33
34    Convenience function.  Connect to *address* (a 2-tuple ``(host,
35    port)``) and return the socket object.  Passing the optional
36    *timeout* parameter will set the timeout on the socket instance
37    before attempting to connect.  If no *timeout* is supplied, the
38    global default timeout setting returned by :func:`getdefaulttimeout`
39    is used.
40    """
41
42    err = "getaddrinfo returns an empty list"
43    host, port = address
44    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
45        af, socktype, proto, canonname, sa = res
46        sock = None
47        try:
48            sock = socket(af, socktype, proto)
49            if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
50                sock.settimeout(timeout)
51            if source_address:
52                sock.bind(source_address)
53            sock.connect(sa)
54            return sock
55
56        except error as e:
57            err = e
58            if sock is not None:
59                sock.close()
60
61    if not isinstance(err, error):
62        err = error(err)
63    raise err
64