qmsk/net/transport/socket.py
author Tero Marttila <terom@fixme.fi>
Sun, 23 Aug 2009 22:59:40 +0300
changeset 37 14db3fe42b6c
parent 33 c71de00715d6
child 45 bb49bf8222ed
permissions -rw-r--r--
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
    Socket implementation helpers
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
"""
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
from qmsk.net.socket import socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
from qmsk.net.socket.constants import *
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
class SocketError (Exception) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
        Base class of errors raised by the Socket classes.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
class SocketBindAddrinfoError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
        The socket was unable to socket()+bind() to the given addrinfo.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
    def __init__ (self, addrinfo, error) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
            addrinfo            - the addrinfo we tried to use
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
            error               - the resulting error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
        self.addrinfo = addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
        self.error = error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
        return "Unable to bind() to %s: %s" % (self.addrinfo, self.error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
class SocketBindEndpointError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
        The socket was unable to bind() to the any of the given endpoint's addresses.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    def __init__ (self, endpoint, errors) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
            endpoint            - the endpoint we tried to bind to
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
            errors              - a sequence of ServiceBindAddrinfoErrors describing the failed bind attempts.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
        self.endpoint = endpoint
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
        self.errors = errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
        # XXX: too verbose?
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
        return "Unable to bind() to any addresses on endpoint %s:\n%s" % (self.endpoint, "\n".join(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
            "\t%s" % (error, ) for error in self.errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
        ))
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
class Base (object) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
        Base class for all other socket-related classes, contains the underlying socket object.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
    # the underlying socket object
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
    sock = None
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
    
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
    def _init_sock (self, sock) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
            Initialize with the given pre-existing socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
        self.sock = sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
class Common (Base) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
        Common operations for Client/Service
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
    72
    # default socktype
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
    73
    _SOCKTYPE = 0
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
    74
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
    @classmethod
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
    76
    def _socket (cls, family, socktype = None, protocol = 0) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
            Construct and return a new socket object using the given parameters.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
    81
        if socktype is None :
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
    82
            socktype = cls._SOCKTYPE
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
    83
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
        return socket.socket(family, socktype, protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
    def _bind_addrinfo (cls, ai) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
            This will attempt to create a new socket and bind it, based on the given addrinfo, returning the new socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
            Raises a ServiceBindAddrinfoError if this fails
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
        try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
            # socket()
33
c71de00715d6 transport.socket fixes
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
    96
            sock = cls._socket(ai.family, ai.socktype, ai.protocol)
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
            # bind()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
            sock.bind(ai.addr)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
        # XXX: except socket.error as e :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
        except OSError, error : 
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
            raise SocketBindAddrinfoError(ai, error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
           
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
            return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
    @classmethod
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   109
    def _bind_endpoint (cls, endpoint, socktype = None, protocol=0) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
            This will resolve the given endpoint, and attempt to create and bind a suitable socket and return it.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
                endpoint        - local Endpoint to bind() to.
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   114
                socktype        - (optiona) socket type to use, defaults to _SOCKTYPE
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
                protocol        - (optional) specific protocol
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
            Raises a ServiceBindError if this is unable to create a bound socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
            XXX: bind to all of the given endpoint's addresses instead of just one...?
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
        errors = []
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
        
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   124
        if socktype is None :
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   125
            socktype = cls._SOCKTYPE
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   126
        
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
        # resolve the endpoint and try socket+bind
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   128
        for ai in endpoint.resolve(socktype, protocol, AI_PASSIVE) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
            try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
                # try to socket+bind this addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
                sock = cls._bind_addrinfo(ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
            except SocketBindAddrinfoError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
                # collect
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
                errors.append(error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
                
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
                # keep trying
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
                continue
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
            else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
                # got a working socket :)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
                return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
       
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
            # no suitable address found :(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
            raise SocketBindEndpointError(endpoint, errors)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
    
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   148
    def _init_endpoint (self, endpoint, socktype = None, protocol = 0, family = None) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
            Initialize this socket by constructing a new socket with the given parameters, bound to the given endpoint,
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
            if given. If no endpoint is given, this simply creates a socket with the given settings and does not bind
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
            it anywhere.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
        """
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   154
        
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   155
        if endpoint is not None :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
            # create a suitable socket bound to a the given endpoint
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   157
            self.sock = self._bind_endpoint(endpoint, socktype, protocol)
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   158
        
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
        else :
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   160
            assert family
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   161
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   162
            # simply create a socket
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
            self.sock = self._socket(family, socktype, protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
class Service (Common) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
        Listener socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
    def _listen (self, backlog) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
            Puts this socket into listen() mode with the given backlog.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        self.sock.listen(backlog)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
class SocketConnectAddrinfoError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        The socket was unable to socket()+connect() to the given addrinfo.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
    def __init__ (self, addrinfo, error) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
            addrinfo            - the addrinfo we tried to use
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
            error               - the resulting error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        self.addrinfo = addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
        self.error = error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        return "Unable to connect() to %s: %s" % (self.addrinfo, self.error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
class SocketConnectEndpointError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
        The socket was unable to connect() to the any of the given endpoint's addresses.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
    def __init__ (self, endpoint, errors) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
            endpoint            - the endpoint we tried to connect to
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
            errors              - a sequence of ServiceBindAddrinfoErrors describing the failed connect attempts.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
        self.endpoint = endpoint
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
        self.errors = errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
        # XXX: too verbose?
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
        return "Unable to connect() to any addresses on endpoint %s:\n%s" % (self.endpoint, "\n".join(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
            "\t%s" % (error, ) for error in self.errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
        ))
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
class Client (Common) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
        Connecting socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
    def _connect_sock_addr (cls, sock, addr) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
            Attempt to connect the given socket to the given address.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
        sock.connect(addr)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
    def _connect_sock_addrinfo (cls, sock, ai) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
            Attempt to connect the given socket to the given addrinfo's address.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
        try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
            cls._connect_sock_addr(sock, ai.addr)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
        # XXX: except socket.error as e :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
        except OSError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
            raise SocketConnectAddrinfoError(ai, error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
    def _connect_addrinfo (cls, ai) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
            Attempt to create a socket and connect it based on the given addrinfo, returning the new socket is succesfull.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
        try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
            # socket()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
            sock = cls._socket(ai.family, ai.socktype, ai.protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
        # XXX: except socket.error as e :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
        except OSError, error : 
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
            raise SocketConnectAddrinfoError(ai, error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
        # try and connect() it
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
        cls._connect_sock_addrinfo(sock, ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
        # return once succesfully
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
        return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
    @classmethod
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   263
    def _connect_sock_endpoint (cls, sock, endpoint, socktype = None, protocol = 0) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
            Connect this socket to the given remote endpoint, using the given parameters to resolve the endpoint.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
        errors = []
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
        
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   270
        if socktype is None :
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   271
            socktype = cls._SOCKTYPE
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   272
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
        # resolve the endpoint and try socket+bind
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   274
        for ai in endpoint.resolve(socktype, protocol) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
            try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
                # try to connect the socket to this addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
                cls._connect_sock_addrinfo(sock, ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
            except SocketConnectAddrinfoError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
                # collect
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
                errors.append(error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
                
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
                # keep trying
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
                continue
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   285
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
            else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
                # got a working socket :)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
                return
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   291
            # no suitable address found :(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   292
            raise SocketConnectEndpointError(endpoint, errors)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   293
    
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   294
    @classmethod
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   295
    def _connect_endpoint (cls, endpoint, socktype = None, protocol = 0) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   296
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   297
            Create a new socket and connect it to the given remote endpoint, using the given parameters to resolve the
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   298
            endpoint.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   299
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   300
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   301
        errors = []
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
        
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   303
        if socktype is None :
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   304
            socktype = cls._SOCKTYPE
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   305
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
        # resolve the endpoint and try socket+bind
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   307
        for ai in endpoint.resolve(socktype, protocol) :
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   308
            try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
                # try to socket+connect this addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   310
                sock = cls._connect_addrinfo(ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   311
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   312
            except SocketConnectAddrinfoError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   313
                # collect
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   314
                errors.append(error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   315
                
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   316
                # keep trying
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   317
                continue
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   318
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   319
            else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   320
                # got a working socket :)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   321
                return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   322
       
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   323
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   324
            # no suitable address found :(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   325
            raise SocketConnectEndpointError(endpoint, errors)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   326
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   327
    def _init_connect_endpoint (self, endpoint, socktype = None, protocol = 0):
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   328
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   329
            If we already have an existing socket, connect it to the given endpoint, otherwise try and connect to the
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   330
            given endpoint with a new socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   331
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   332
            There is a subtle difference here, because if we have e.g. an IPv4 socket and try and connect it to an
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   333
            endpoint with both IPv6 and IPv4 addresses, we will try to connect to an IPv6 address using the IPv4 socket,
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   334
            and then to the IPv4 address using the IPv6 socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   335
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   336
            If we do not yet have a socket, then we will attempt to connect to the IPv6 address using an IPv6 socket,
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   337
            and to the IPv4 address using an IPv4 socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   338
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   339
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   340
        if self.socket :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   341
            # connect with existing socket
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   342
            self._connect_sock_endpoint(self.socket, endpoint, socktype, protocol)
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   343
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   345
            # connect with new socket
37
14db3fe42b6c move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents: 33
diff changeset
   346
            self._connect_endpoint(endpoint, socktype, protocol)
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   347
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   348
class Stream (Base) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   349
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   350
        Unbuffered byte-stream interface.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   351
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   352
   
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   353
    def read (self, iov) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   354
        return self.sock.read(iov)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   355
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   356
    def readv (self, iovecs) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   357
        return self.sock.readv(iovecs)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   358
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   359
    def write (self, buf) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   360
        return self.sock.write(buf)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   361
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   362
    def writev (self, iovecs) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   363
        return self.sock.writev(iovecs)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   364
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   365
    def close (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   366
        self.sock.close()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   367
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   368
    def abort (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   369
        # XXX: SO_LINGER magic
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   370
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   371
        raise NotImplementedError()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   372
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   373