PageRenderTime 60ms CodeModel.GetById 13ms app.highlight 39ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/socket.py

https://bitbucket.org/yomgui/cpython
Python | 736 lines | 708 code | 1 blank | 27 comment | 8 complexity | 73c09a22845a9f6af87b3d37ae325532 MD5 | raw file
  1# Wrapper module for _socket, providing some additional facilities
  2# implemented in Python.
  3
  4"""\
  5This module provides socket operations and some related functions.
  6On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
  7On other systems, it only supports IP. Functions specific for a
  8socket are available as methods of the socket object.
  9
 10Functions:
 11
 12socket() -- create a new socket object
 13socketpair() -- create a pair of new socket objects [*]
 14fromfd() -- create a socket object from an open file descriptor [*]
 15fromshare() -- create a socket object from data received from socket.share() [*]
 16gethostname() -- return the current hostname
 17gethostbyname() -- map a hostname to its IP number
 18gethostbyaddr() -- map an IP number or hostname to DNS info
 19getservbyname() -- map a service name and a protocol name to a port number
 20getprotobyname() -- map a protocol name (e.g. 'tcp') to a number
 21ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order
 22htons(), htonl() -- convert 16, 32 bit int from host to network byte order
 23inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
 24inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
 25socket.getdefaulttimeout() -- get the default timeout value
 26socket.setdefaulttimeout() -- set the default timeout value
 27create_connection() -- connects to an address, with an optional timeout and
 28                       optional source address.
 29
 30 [*] not available on all platforms!
 31
 32Special objects:
 33
 34SocketType -- type object for socket objects
 35error -- exception raised for I/O errors
 36has_ipv6 -- boolean value indicating if IPv6 is supported
 37
 38IntEnum constants:
 39
 40AF_INET, AF_UNIX -- socket domains (first argument to socket() call)
 41SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument)
 42
 43Integer constants:
 44
 45Many other constants may be defined; these may be used in calls to
 46the setsockopt() and getsockopt() methods.
 47"""
 48
 49import _socket
 50from _socket import *
 51
 52import os, sys, io, selectors
 53from enum import IntEnum
 54
 55try:
 56    import errno
 57except ImportError:
 58    errno = None
 59EBADF = getattr(errno, 'EBADF', 9)
 60EAGAIN = getattr(errno, 'EAGAIN', 11)
 61EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11)
 62
 63__all__ = ["fromfd", "getfqdn", "create_connection",
 64        "AddressFamily", "SocketKind"]
 65__all__.extend(os._get_exports_list(_socket))
 66
 67# Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for
 68# nicer string representations.
 69# Note that _socket only knows about the integer values. The public interface
 70# in this module understands the enums and translates them back from integers
 71# where needed (e.g. .family property of a socket object).
 72AddressFamily = IntEnum('AddressFamily',
 73                        {name: value for name, value in globals().items()
 74                         if name.isupper() and name.startswith('AF_')})
 75globals().update(AddressFamily.__members__)
 76
 77SocketKind = IntEnum('SocketKind',
 78                     {name: value for name, value in globals().items()
 79                      if name.isupper() and name.startswith('SOCK_')})
 80globals().update(SocketKind.__members__)
 81
 82
 83_LOCALHOST    = '127.0.0.1'
 84_LOCALHOST_V6 = '::1'
 85
 86
 87def _intenum_converter(value, enum_klass):
 88    """Convert a numeric family value to an IntEnum member.
 89
 90    If it's not a known member, return the numeric value itself.
 91    """
 92    try:
 93        return enum_klass(value)
 94    except ValueError:
 95        return value
 96
 97_realsocket = socket
 98
 99# WSA error codes
100if sys.platform.lower().startswith("win"):
101    errorTab = {}
102    errorTab[10004] = "The operation was interrupted."
103    errorTab[10009] = "A bad file handle was passed."
104    errorTab[10013] = "Permission denied."
105    errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT
106    errorTab[10022] = "An invalid operation was attempted."
107    errorTab[10035] = "The socket operation would block"
108    errorTab[10036] = "A blocking operation is already in progress."
109    errorTab[10048] = "The network address is in use."
110    errorTab[10054] = "The connection has been reset."
111    errorTab[10058] = "The network has been shut down."
112    errorTab[10060] = "The operation timed out."
113    errorTab[10061] = "Connection refused."
114    errorTab[10063] = "The name is too long."
115    errorTab[10064] = "The host is down."
116    errorTab[10065] = "The host is unreachable."
117    __all__.append("errorTab")
118
119
120class _GiveupOnSendfile(Exception): pass
121
122
123class socket(_socket.socket):
124
125    """A subclass of _socket.socket adding the makefile() method."""
126
127    __slots__ = ["__weakref__", "_io_refs", "_closed"]
128
129    def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None):
130        # For user code address family and type values are IntEnum members, but
131        # for the underlying _socket.socket they're just integers. The
132        # constructor of _socket.socket converts the given argument to an
133        # integer automatically.
134        _socket.socket.__init__(self, family, type, proto, fileno)
135        self._io_refs = 0
136        self._closed = False
137
138    def __enter__(self):
139        return self
140
141    def __exit__(self, *args):
142        if not self._closed:
143            self.close()
144
145    def __repr__(self):
146        """Wrap __repr__() to reveal the real class name and socket
147        address(es).
148        """
149        closed = getattr(self, '_closed', False)
150        s = "<%s.%s%s fd=%i, family=%s, type=%s, proto=%i" \
151            % (self.__class__.__module__,
152               self.__class__.__qualname__,
153               " [closed]" if closed else "",
154               self.fileno(),
155               self.family,
156               self.type,
157               self.proto)
158        if not closed:
159            try:
160                laddr = self.getsockname()
161                if laddr:
162                    s += ", laddr=%s" % str(laddr)
163            except error:
164                pass
165            try:
166                raddr = self.getpeername()
167                if raddr:
168                    s += ", raddr=%s" % str(raddr)
169            except error:
170                pass
171        s += '>'
172        return s
173
174    def __getstate__(self):
175        raise TypeError("Cannot serialize socket object")
176
177    def dup(self):
178        """dup() -> socket object
179
180        Duplicate the socket. Return a new socket object connected to the same
181        system resource. The new socket is non-inheritable.
182        """
183        fd = dup(self.fileno())
184        sock = self.__class__(self.family, self.type, self.proto, fileno=fd)
185        sock.settimeout(self.gettimeout())
186        return sock
187
188    def accept(self):
189        """accept() -> (socket object, address info)
190
191        Wait for an incoming connection.  Return a new socket
192        representing the connection, and the address of the client.
193        For IP sockets, the address info is a pair (hostaddr, port).
194        """
195        fd, addr = self._accept()
196        sock = socket(self.family, self.type, self.proto, fileno=fd)
197        # Issue #7995: if no default timeout is set and the listening
198        # socket had a (non-zero) timeout, force the new socket in blocking
199        # mode to override platform-specific socket flags inheritance.
200        if getdefaulttimeout() is None and self.gettimeout():
201            sock.setblocking(True)
202        return sock, addr
203
204    def makefile(self, mode="r", buffering=None, *,
205                 encoding=None, errors=None, newline=None):
206        """makefile(...) -> an I/O stream connected to the socket
207
208        The arguments are as for io.open() after the filename,
209        except the only mode characters supported are 'r', 'w' and 'b'.
210        The semantics are similar too.  (XXX refactor to share code?)
211        """
212        for c in mode:
213            if c not in {"r", "w", "b"}:
214                raise ValueError("invalid mode %r (only r, w, b allowed)")
215        writing = "w" in mode
216        reading = "r" in mode or not writing
217        assert reading or writing
218        binary = "b" in mode
219        rawmode = ""
220        if reading:
221            rawmode += "r"
222        if writing:
223            rawmode += "w"
224        raw = SocketIO(self, rawmode)
225        self._io_refs += 1
226        if buffering is None:
227            buffering = -1
228        if buffering < 0:
229            buffering = io.DEFAULT_BUFFER_SIZE
230        if buffering == 0:
231            if not binary:
232                raise ValueError("unbuffered streams must be binary")
233            return raw
234        if reading and writing:
235            buffer = io.BufferedRWPair(raw, raw, buffering)
236        elif reading:
237            buffer = io.BufferedReader(raw, buffering)
238        else:
239            assert writing
240            buffer = io.BufferedWriter(raw, buffering)
241        if binary:
242            return buffer
243        text = io.TextIOWrapper(buffer, encoding, errors, newline)
244        text.mode = mode
245        return text
246
247    if hasattr(os, 'sendfile'):
248
249        def _sendfile_use_sendfile(self, file, offset=0, count=None):
250            self._check_sendfile_params(file, offset, count)
251            sockno = self.fileno()
252            try:
253                fileno = file.fileno()
254            except (AttributeError, io.UnsupportedOperation) as err:
255                raise _GiveupOnSendfile(err)  # not a regular file
256            try:
257                fsize = os.fstat(fileno).st_size
258            except OSError:
259                raise _GiveupOnSendfile(err)  # not a regular file
260            if not fsize:
261                return 0  # empty file
262            blocksize = fsize if not count else count
263
264            timeout = self.gettimeout()
265            if timeout == 0:
266                raise ValueError("non-blocking sockets are not supported")
267            # poll/select have the advantage of not requiring any
268            # extra file descriptor, contrarily to epoll/kqueue
269            # (also, they require a single syscall).
270            if hasattr(selectors, 'PollSelector'):
271                selector = selectors.PollSelector()
272            else:
273                selector = selectors.SelectSelector()
274            selector.register(sockno, selectors.EVENT_WRITE)
275
276            total_sent = 0
277            # localize variable access to minimize overhead
278            selector_select = selector.select
279            os_sendfile = os.sendfile
280            try:
281                while True:
282                    if timeout and not selector_select(timeout):
283                        raise _socket.timeout('timed out')
284                    if count:
285                        blocksize = count - total_sent
286                        if blocksize <= 0:
287                            break
288                    try:
289                        sent = os_sendfile(sockno, fileno, offset, blocksize)
290                    except BlockingIOError:
291                        if not timeout:
292                            # Block until the socket is ready to send some
293                            # data; avoids hogging CPU resources.
294                            selector_select()
295                        continue
296                    except OSError as err:
297                        if total_sent == 0:
298                            # We can get here for different reasons, the main
299                            # one being 'file' is not a regular mmap(2)-like
300                            # file, in which case we'll fall back on using
301                            # plain send().
302                            raise _GiveupOnSendfile(err)
303                        raise err from None
304                    else:
305                        if sent == 0:
306                            break  # EOF
307                        offset += sent
308                        total_sent += sent
309                return total_sent
310            finally:
311                if total_sent > 0 and hasattr(file, 'seek'):
312                    file.seek(offset)
313    else:
314        def _sendfile_use_sendfile(self, file, offset=0, count=None):
315            raise _GiveupOnSendfile(
316                "os.sendfile() not available on this platform")
317
318    def _sendfile_use_send(self, file, offset=0, count=None):
319        self._check_sendfile_params(file, offset, count)
320        if self.gettimeout() == 0:
321            raise ValueError("non-blocking sockets are not supported")
322        if offset:
323            file.seek(offset)
324        blocksize = min(count, 8192) if count else 8192
325        total_sent = 0
326        # localize variable access to minimize overhead
327        file_read = file.read
328        sock_send = self.send
329        try:
330            while True:
331                if count:
332                    blocksize = min(count - total_sent, blocksize)
333                    if blocksize <= 0:
334                        break
335                data = memoryview(file_read(blocksize))
336                if not data:
337                    break  # EOF
338                while True:
339                    try:
340                        sent = sock_send(data)
341                    except BlockingIOError:
342                        continue
343                    else:
344                        total_sent += sent
345                        if sent < len(data):
346                            data = data[sent:]
347                        else:
348                            break
349            return total_sent
350        finally:
351            if total_sent > 0 and hasattr(file, 'seek'):
352                file.seek(offset + total_sent)
353
354    def _check_sendfile_params(self, file, offset, count):
355        if 'b' not in getattr(file, 'mode', 'b'):
356            raise ValueError("file should be opened in binary mode")
357        if not self.type & SOCK_STREAM:
358            raise ValueError("only SOCK_STREAM type sockets are supported")
359        if count is not None:
360            if not isinstance(count, int):
361                raise TypeError(
362                    "count must be a positive integer (got {!r})".format(count))
363            if count <= 0:
364                raise ValueError(
365                    "count must be a positive integer (got {!r})".format(count))
366
367    def sendfile(self, file, offset=0, count=None):
368        """sendfile(file[, offset[, count]]) -> sent
369
370        Send a file until EOF is reached by using high-performance
371        os.sendfile() and return the total number of bytes which
372        were sent.
373        *file* must be a regular file object opened in binary mode.
374        If os.sendfile() is not available (e.g. Windows) or file is
375        not a regular file socket.send() will be used instead.
376        *offset* tells from where to start reading the file.
377        If specified, *count* is the total number of bytes to transmit
378        as opposed to sending the file until EOF is reached.
379        File position is updated on return or also in case of error in
380        which case file.tell() can be used to figure out the number of
381        bytes which were sent.
382        The socket must be of SOCK_STREAM type.
383        Non-blocking sockets are not supported.
384        """
385        try:
386            return self._sendfile_use_sendfile(file, offset, count)
387        except _GiveupOnSendfile:
388            return self._sendfile_use_send(file, offset, count)
389
390    def _decref_socketios(self):
391        if self._io_refs > 0:
392            self._io_refs -= 1
393        if self._closed:
394            self.close()
395
396    def _real_close(self, _ss=_socket.socket):
397        # This function should not reference any globals. See issue #808164.
398        _ss.close(self)
399
400    def close(self):
401        # This function should not reference any globals. See issue #808164.
402        self._closed = True
403        if self._io_refs <= 0:
404            self._real_close()
405
406    def detach(self):
407        """detach() -> file descriptor
408
409        Close the socket object without closing the underlying file descriptor.
410        The object cannot be used after this call, but the file descriptor
411        can be reused for other purposes.  The file descriptor is returned.
412        """
413        self._closed = True
414        return super().detach()
415
416    @property
417    def family(self):
418        """Read-only access to the address family for this socket.
419        """
420        return _intenum_converter(super().family, AddressFamily)
421
422    @property
423    def type(self):
424        """Read-only access to the socket type.
425        """
426        return _intenum_converter(super().type, SocketKind)
427
428    if os.name == 'nt':
429        def get_inheritable(self):
430            return os.get_handle_inheritable(self.fileno())
431        def set_inheritable(self, inheritable):
432            os.set_handle_inheritable(self.fileno(), inheritable)
433    else:
434        def get_inheritable(self):
435            return os.get_inheritable(self.fileno())
436        def set_inheritable(self, inheritable):
437            os.set_inheritable(self.fileno(), inheritable)
438    get_inheritable.__doc__ = "Get the inheritable flag of the socket"
439    set_inheritable.__doc__ = "Set the inheritable flag of the socket"
440
441def fromfd(fd, family, type, proto=0):
442    """ fromfd(fd, family, type[, proto]) -> socket object
443
444    Create a socket object from a duplicate of the given file
445    descriptor.  The remaining arguments are the same as for socket().
446    """
447    nfd = dup(fd)
448    return socket(family, type, proto, nfd)
449
450if hasattr(_socket.socket, "share"):
451    def fromshare(info):
452        """ fromshare(info) -> socket object
453
454        Create a socket object from a the bytes object returned by
455        socket.share(pid).
456        """
457        return socket(0, 0, 0, info)
458    __all__.append("fromshare")
459
460if hasattr(_socket, "socketpair"):
461
462    def socketpair(family=None, type=SOCK_STREAM, proto=0):
463        """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
464
465        Create a pair of socket objects from the sockets returned by the platform
466        socketpair() function.
467        The arguments are the same as for socket() except the default family is
468        AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
469        """
470        if family is None:
471            try:
472                family = AF_UNIX
473            except NameError:
474                family = AF_INET
475        a, b = _socket.socketpair(family, type, proto)
476        a = socket(family, type, proto, a.detach())
477        b = socket(family, type, proto, b.detach())
478        return a, b
479
480else:
481
482    # Origin: https://gist.github.com/4325783, by Geert Jansen.  Public domain.
483    def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
484        if family == AF_INET:
485            host = _LOCALHOST
486        elif family == AF_INET6:
487            host = _LOCALHOST_V6
488        else:
489            raise ValueError("Only AF_INET and AF_INET6 socket address families "
490                             "are supported")
491        if type != SOCK_STREAM:
492            raise ValueError("Only SOCK_STREAM socket type is supported")
493        if proto != 0:
494            raise ValueError("Only protocol zero is supported")
495
496        # We create a connected TCP socket. Note the trick with
497        # setblocking(False) that prevents us from having to create a thread.
498        lsock = socket(family, type, proto)
499        try:
500            lsock.bind((host, 0))
501            lsock.listen()
502            # On IPv6, ignore flow_info and scope_id
503            addr, port = lsock.getsockname()[:2]
504            csock = socket(family, type, proto)
505            try:
506                csock.setblocking(False)
507                try:
508                    csock.connect((addr, port))
509                except (BlockingIOError, InterruptedError):
510                    pass
511                csock.setblocking(True)
512                ssock, _ = lsock.accept()
513            except:
514                csock.close()
515                raise
516        finally:
517            lsock.close()
518        return (ssock, csock)
519
520socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
521Create a pair of socket objects from the sockets returned by the platform
522socketpair() function.
523The arguments are the same as for socket() except the default family is AF_UNIX
524if defined on the platform; otherwise, the default is AF_INET.
525"""
526
527_blocking_errnos = { EAGAIN, EWOULDBLOCK }
528
529class SocketIO(io.RawIOBase):
530
531    """Raw I/O implementation for stream sockets.
532
533    This class supports the makefile() method on sockets.  It provides
534    the raw I/O interface on top of a socket object.
535    """
536
537    # One might wonder why not let FileIO do the job instead.  There are two
538    # main reasons why FileIO is not adapted:
539    # - it wouldn't work under Windows (where you can't used read() and
540    #   write() on a socket handle)
541    # - it wouldn't work with socket timeouts (FileIO would ignore the
542    #   timeout and consider the socket non-blocking)
543
544    # XXX More docs
545
546    def __init__(self, sock, mode):
547        if mode not in ("r", "w", "rw", "rb", "wb", "rwb"):
548            raise ValueError("invalid mode: %r" % mode)
549        io.RawIOBase.__init__(self)
550        self._sock = sock
551        if "b" not in mode:
552            mode += "b"
553        self._mode = mode
554        self._reading = "r" in mode
555        self._writing = "w" in mode
556        self._timeout_occurred = False
557
558    def readinto(self, b):
559        """Read up to len(b) bytes into the writable buffer *b* and return
560        the number of bytes read.  If the socket is non-blocking and no bytes
561        are available, None is returned.
562
563        If *b* is non-empty, a 0 return value indicates that the connection
564        was shutdown at the other end.
565        """
566        self._checkClosed()
567        self._checkReadable()
568        if self._timeout_occurred:
569            raise OSError("cannot read from timed out object")
570        while True:
571            try:
572                return self._sock.recv_into(b)
573            except timeout:
574                self._timeout_occurred = True
575                raise
576            except InterruptedError:
577                continue
578            except error as e:
579                if e.args[0] in _blocking_errnos:
580                    return None
581                raise
582
583    def write(self, b):
584        """Write the given bytes or bytearray object *b* to the socket
585        and return the number of bytes written.  This can be less than
586        len(b) if not all data could be written.  If the socket is
587        non-blocking and no bytes could be written None is returned.
588        """
589        self._checkClosed()
590        self._checkWritable()
591        try:
592            return self._sock.send(b)
593        except error as e:
594            # XXX what about EINTR?
595            if e.args[0] in _blocking_errnos:
596                return None
597            raise
598
599    def readable(self):
600        """True if the SocketIO is open for reading.
601        """
602        if self.closed:
603            raise ValueError("I/O operation on closed socket.")
604        return self._reading
605
606    def writable(self):
607        """True if the SocketIO is open for writing.
608        """
609        if self.closed:
610            raise ValueError("I/O operation on closed socket.")
611        return self._writing
612
613    def seekable(self):
614        """True if the SocketIO is open for seeking.
615        """
616        if self.closed:
617            raise ValueError("I/O operation on closed socket.")
618        return super().seekable()
619
620    def fileno(self):
621        """Return the file descriptor of the underlying socket.
622        """
623        self._checkClosed()
624        return self._sock.fileno()
625
626    @property
627    def name(self):
628        if not self.closed:
629            return self.fileno()
630        else:
631            return -1
632
633    @property
634    def mode(self):
635        return self._mode
636
637    def close(self):
638        """Close the SocketIO object.  This doesn't close the underlying
639        socket, except if all references to it have disappeared.
640        """
641        if self.closed:
642            return
643        io.RawIOBase.close(self)
644        self._sock._decref_socketios()
645        self._sock = None
646
647
648def getfqdn(name=''):
649    """Get fully qualified domain name from name.
650
651    An empty argument is interpreted as meaning the local host.
652
653    First the hostname returned by gethostbyaddr() is checked, then
654    possibly existing aliases. In case no FQDN is available, hostname
655    from gethostname() is returned.
656    """
657    name = name.strip()
658    if not name or name == '0.0.0.0':
659        name = gethostname()
660    try:
661        hostname, aliases, ipaddrs = gethostbyaddr(name)
662    except error:
663        pass
664    else:
665        aliases.insert(0, hostname)
666        for name in aliases:
667            if '.' in name:
668                break
669        else:
670            name = hostname
671    return name
672
673
674_GLOBAL_DEFAULT_TIMEOUT = object()
675
676def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT,
677                      source_address=None):
678    """Connect to *address* and return the socket object.
679
680    Convenience function.  Connect to *address* (a 2-tuple ``(host,
681    port)``) and return the socket object.  Passing the optional
682    *timeout* parameter will set the timeout on the socket instance
683    before attempting to connect.  If no *timeout* is supplied, the
684    global default timeout setting returned by :func:`getdefaulttimeout`
685    is used.  If *source_address* is set it must be a tuple of (host, port)
686    for the socket to bind as a source address before making the connection.
687    An host of '' or port 0 tells the OS to use the default.
688    """
689
690    host, port = address
691    err = None
692    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
693        af, socktype, proto, canonname, sa = res
694        sock = None
695        try:
696            sock = socket(af, socktype, proto)
697            if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
698                sock.settimeout(timeout)
699            if source_address:
700                sock.bind(source_address)
701            sock.connect(sa)
702            return sock
703
704        except error as _:
705            err = _
706            if sock is not None:
707                sock.close()
708
709    if err is not None:
710        raise err
711    else:
712        raise error("getaddrinfo returns an empty list")
713
714def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
715    """Resolve host and port into list of address info entries.
716
717    Translate the host/port argument into a sequence of 5-tuples that contain
718    all the necessary arguments for creating a socket connected to that service.
719    host is a domain name, a string representation of an IPv4/v6 address or
720    None. port is a string service name such as 'http', a numeric port number or
721    None. By passing None as the value of host and port, you can pass NULL to
722    the underlying C API.
723
724    The family, type and proto arguments can be optionally specified in order to
725    narrow the list of addresses returned. Passing zero as a value for each of
726    these arguments selects the full range of results.
727    """
728    # We override this function since we want to translate the numeric family
729    # and socket type values to enum constants.
730    addrlist = []
731    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
732        af, socktype, proto, canonname, sa = res
733        addrlist.append((_intenum_converter(af, AddressFamily),
734                         _intenum_converter(socktype, SocketKind),
735                         proto, canonname, sa))
736    return addrlist