reorganize transport.endpoint
authorTero Marttila <terom@fixme.fi>
Sun, 23 Aug 2009 23:12:29 +0300
changeset 38 f0fc793a3754
parent 37 14db3fe42b6c
child 39 075eaafa80a7
reorganize transport.endpoint
qmsk/net/transport/endpoint.py
test/transport_tcp.py
--- a/qmsk/net/transport/endpoint.py	Sun Aug 23 22:59:40 2009 +0300
+++ b/qmsk/net/transport/endpoint.py	Sun Aug 23 23:12:29 2009 +0300
@@ -8,7 +8,8 @@
 
 class Endpoint (object) :
     """
-        Abstract network address interface, 
+        Abstract network address interface. This can map to multiple actual addresses, potentially of different
+        address families.
     """
 
     def resolve (self, socktype, protocol = 0, passive = True) :
@@ -18,10 +19,9 @@
         
         raise NotImplemented()
 
-
-class InetAddr (Endpoint) :
+class InetEndpoint (Endpoint) :
     """
-        An internet address, either IPv4 or IPv6.
+        An internet endpoint, supports IPv4, IPv6 addresses and DNS hostnames.
 
            hostname     - [str] literal address or DNS hostname
            service      - [str] port number or service name
@@ -56,53 +56,77 @@
 
         return self.endpoint.getaddrinfo(self.family, socktype, protocol, flags)
 
-class UnixAddr (Endpoint) :
-    """
-        A local AF_UNIX address, as a path.
+class Address (Endpoint) :
     """
-
-    def __init__ (self, path) :
-        self.path = path
-        self.addr = af_unix.sockaddr_un(path)
-
-    def resolve (self, socktype, protocol = 0, passive = True) :
-        if not socktype :
-            raise ValueError("Unknown socktype: %s" % (socktype, ))
-
-        return [AddrInfo(0, constants.AF_UNIX, socktype, protocol, self.addr, self.path)]
-
-class SockAddr (Endpoint) :
-    """
-        A specific address, suitable both as an endpoint.
+        A specific socket-level address of some address family, also useable as an Endpoint.
 
             addr        - low-level sockaddr object
             family      - AF_*
-            socktype    - SOCK_*
     """
 
-    def __init__ (self, addr, family = constants.AF_UNSPEC, socktype = 0) :
+    def __init__ (self, sockaddr, family = constants.AF_UNSPEC, canonical = None) :
         if not family :
-            family = addr.family
+            family = sockaddr.family
 
-        self.addr = addr
+        if not canonical :
+            # XXX: delay?
+            canonical = str(sockaddr)
+
+        self._sockaddr = sockaddr
         self.family = family
-        self.socktype = socktype
+        self.canonical = canonical
+    
+    def sockaddr (self) :
+        """
+            Returns a qmsk.net.socket.address.sockaddr object for this address.
+        """
+
+        return self._sockaddr
 
     def resolve (self, socktype, protocol = 0, passive = True) :
         """
             Returns a single AddrInfo object representing this address 
         """
     
-        if socktype and self.socktype and socktype != self.socktype :
-            raise ValueError("Socket type mismatch: %s should be %s" % (socktype, self.socktype))
-
         if not socktype :
-            if self.socktype :
-                socktype = self.socktype
+            raise ValueError("Socket type unknown")
 
-            else :
-                raise ValueError("Socket type unknown")
+        return [AddrInfo(0, self.family, socktype, protocol, self._sockaddr, self.canonical)]
 
+class InetAddr (Address) :
+    """
+        An AF_INET/AF_INET6 address, with addr and port.
+    """
+    
+    @property
+    def addr (self) :
+        return self._sockaddr.addr
 
-        return [AddrInfo(0, self.family, socktype, protocol, self.addr, None)]
+    @property
+    def port (self) :
+        return self._sockaddr.port
 
+class IPv4Addr (InetAddr) :
+    """
+        A fixed AF_INET address and port
+    """
+
+    def __init__ (self, addr, port) :
+        super(IPv4Addr, self).__init__(af_inet.sockaddr_in(addr, port))
+
+class IPv6Addr (InetAddr) :
+    """
+        A fixed AF_INET6 address and port
+    """
+
+    def __init__ (self, addr, port) :
+        super(IPv6Addr, self).__init__(af_inet6.sockaddr_in6(addr, port))
+
+class UnixAddr (Address) :
+    """
+        A local AF_UNIX address, as a path.
+    """
+
+    def __init__ (self, path) :
+        super(UnixAddr, self).__init__(af_unix.sockaddr_un(path))
+
--- a/test/transport_tcp.py	Sun Aug 23 22:59:40 2009 +0300
+++ b/test/transport_tcp.py	Sun Aug 23 23:12:29 2009 +0300
@@ -33,7 +33,7 @@
         self.ls.listen(1)
 
         self.sockaddr = af_inet.sockaddr_in('127.0.0.1', self.ls.getsockname().port)
-        self.addr = endpoint.SockAddr(self.sockaddr)
+        self.addr = endpoint.Address(self.sockaddr)
    
     def test_connect (self) :
         cc = tcp.Client(self.addr)
@@ -45,7 +45,7 @@
         sockaddr = af_inet.sockaddr_in('127.0.0.1', self.sockaddr.port + 1)
         
         # connect with bind()
-        cc = tcp.Client(self.addr, bind_endpoint=endpoint.SockAddr(sockaddr))
+        cc = tcp.Client(self.addr, bind_endpoint=endpoint.Address(sockaddr))
         cs = cc.connect()
 
         self.assertEquals(cs.sock.getsockname(), sockaddr)
@@ -55,13 +55,13 @@
         sockaddr = af_inet6.sockaddr_in6('::1', self.sockaddr.port + 1)
         
         # connect with bind()
-        cc = tcp.Client(self.addr, bind_endpoint=endpoint.SockAddr(sockaddr))
+        cc = tcp.Client(self.addr, bind_endpoint=endpoint.Address(sockaddr))
         
         # should fail (IPv6 -> IPv4)
         self.assertRaises(socket.SocketConnectEndpointError, cc.connect)
     
     def test_connect_inet (self) :
-        cc = tcp.Client(endpoint.InetAddr('localhost', self.sockaddr.port))
+        cc = tcp.Client(endpoint.InetEndpoint('localhost', self.sockaddr.port))
         cs = cc.connect()
 
         self.assertEquals(cs.sock.getpeername(), self.sockaddr)