Alberto Bertogli added the comment:

On Sun, Jan 06, 2008 at 02:45:35PM -0000, Alberto Bertogli wrote:
> I'll probably send you the updated patch sometime this week; thanks for
> the ping =)

Here are the three patches, rebased to the SVN commit 59815.

The first one is the same I've already submitted, the second adds the
documentation and the third two testcases.

The testcases are simple, but I think cover a reasonable amount of TIPC
specific code. If you want more, let me know.

The documentation is simple, as you told me, just a paragraph explaining
about the address format and another explaining the constants. Again, if
you want me to change anything, just let me know.

Finally, if you want me to rebase this on top of any other branch, you
guessed it, just let me know ;)

Thanks a lot,
                Alberto

Added file: http://bugs.python.org/file9092/0001-Make-socket-support-TIPC.patch
Added file: 
http://bugs.python.org/file9093/0002-Add-documentation-and-Misc-NEWS-entry-for-TIPC-suppo.patch
Added file: 
http://bugs.python.org/file9094/0003-Add-unit-tests-for-TIPC-socket-support.patch

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1646>
__________________________________
>From b643e5cad1f4fe32ed03847bd2e55bbae76b5e8b Mon Sep 17 00:00:00 2001
From: Alberto Bertogli <[EMAIL PROTECTED]>
Date: Wed, 5 Dec 2007 18:39:18 -0300
Subject: [PATCH] Make socket support TIPC.

TIPC (http://tipc.sf.net) is an open protocol designed for use in
clustered computer environments. It currently has an open source
implementation for Linux (>= 2.6.16), and VxWorks.

This patch adds optional Linux-only support for TIPC in the socket module.
---
 Modules/socketmodule.c |  154 +++++++++++++++++++++++++++++++++++++++++++++++-
 Modules/socketmodule.h |    4 +
 configure.in           |    2 +-
 3 files changed, 158 insertions(+), 2 deletions(-)

diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index c30f1b3..e3f81db 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -7,7 +7,8 @@ This module provides an interface to Berkeley socket IPC.
 Limitations:
 
 - Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a
-  portable manner, though AF_PACKET and AF_NETLINK are supported under Linux.
+  portable manner, though AF_PACKET, AF_NETLINK and AF_TIPC are supported
+  under Linux.
 - No read/write operations (use sendall/recv or makefile instead).
 - Additional restrictions apply on some non-Unix platforms (compensated
   for by socket.py).
@@ -52,6 +53,25 @@ Module interface:
   the Ethernet protocol number to be received. For example:
   ("eth0",0x1234).  Optional 3rd,4th,5th elements in the tuple
   specify packet-type and ha-type/addr.
+- an AF_TIPC socket address is expressed as
+ (addr_type, v1, v2, v3 [, scope]); where addr_type can be one of:
+       TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID;
+  and scope can be one of:
+       TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and TIPC_NODE_SCOPE.
+  The meaning of v1, v2 and v3 depends on the value of addr_type:
+       if addr_type is TIPC_ADDR_NAME:
+               v1 is the server type
+               v2 is the port identifier
+               v3 is ignored
+       if addr_type is TIPC_ADDR_NAMESEQ:
+               v1 is the server type
+               v2 is the lower port number
+               v3 is the upper port number
+       if addr_type is TIPC_ADDR_ID:
+               v1 is the node
+               v2 is the ref
+               v3 is ignored
+
 
 Local naming conventions:
 
@@ -1094,6 +1114,39 @@ makesockaddr(int sockfd, struct sockaddr *addr, int 
addrlen, int proto)
        }
 #endif
 
+#ifdef HAVE_LINUX_TIPC_H
+       case AF_TIPC:
+       {
+               struct sockaddr_tipc *a = (struct sockaddr_tipc *) addr;
+               if (a->addrtype == TIPC_ADDR_NAMESEQ) {
+                       return Py_BuildValue("IIIII",
+                                       a->addrtype,
+                                       a->addr.nameseq.type,
+                                       a->addr.nameseq.lower,
+                                       a->addr.nameseq.upper,
+                                       a->scope);
+               } else if (a->addrtype == TIPC_ADDR_NAME) {
+                       return Py_BuildValue("IIIII",
+                                       a->addrtype,
+                                       a->addr.name.name.type,
+                                       a->addr.name.name.instance,
+                                       a->addr.name.name.instance,
+                                       a->scope);
+               } else if (a->addrtype == TIPC_ADDR_ID) {
+                       return Py_BuildValue("IIIII",
+                                       a->addrtype,
+                                       a->addr.id.node,
+                                       a->addr.id.ref,
+                                       0,
+                                       a->scope);
+               } else {
+                       PyErr_SetString(PyExc_TypeError,
+                                       "Invalid address type");
+                       return NULL;
+               }
+       }
+#endif
+
        /* More cases here... */
 
        default:
@@ -1379,6 +1432,56 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
        }
 #endif
 
+#ifdef HAVE_LINUX_TIPC_H
+       case AF_TIPC:
+       {
+               unsigned int atype, v1, v2, v3;
+               unsigned int scope = TIPC_CLUSTER_SCOPE;
+               struct sockaddr_tipc *addr;
+
+               if (!PyTuple_Check(args)) {
+                       PyErr_Format(
+                               PyExc_TypeError,
+                               "getsockaddrarg: "
+                               "AF_TIPC address must be tuple, not %.500s",
+                               Py_TYPE(args)->tp_name);
+                       return 0;
+               }
+
+               if (!PyArg_ParseTuple(args,
+                                       "IIII|I;Invalid TIPC address format",
+                                       &atype, &v1, &v2, &v3, &scope))
+                       return 0;
+
+               addr = (struct sockaddr_tipc *) addr_ret;
+               memset(addr, 0, sizeof(struct sockaddr_tipc));
+
+               addr->family = AF_TIPC;
+               addr->scope = scope;
+               addr->addrtype = atype;
+
+               if (atype == TIPC_ADDR_NAMESEQ) {
+                       addr->addr.nameseq.type = v1;
+                       addr->addr.nameseq.lower = v2;
+                       addr->addr.nameseq.upper = v3;
+               } else if (atype == TIPC_ADDR_NAME) {
+                       addr->addr.name.name.type = v1;
+                       addr->addr.name.name.instance = v2;
+               } else if (atype == TIPC_ADDR_ID) {
+                       addr->addr.id.node = v1;
+                       addr->addr.id.ref = v2;
+               } else {
+                       /* Shouldn't happen */
+                       PyErr_SetString(PyExc_TypeError, "Invalid address 
type");
+                       return 0;
+               }
+
+               *len_ret = sizeof(*addr);
+
+               return 1;
+       }
+#endif
+
        /* More cases here... */
 
        default:
@@ -1464,6 +1567,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
        }
 #endif
 
+#ifdef HAVE_LINUX_TIPC_H
+       case AF_TIPC:
+       {
+               *len_ret = sizeof (struct sockaddr_tipc);
+               return 1;
+       }
+#endif
+
        /* More cases here... */
 
        default:
@@ -4448,6 +4559,47 @@ init_socket(void)
        PyModule_AddIntConstant(m, "PACKET_FASTROUTE", PACKET_FASTROUTE);
 #endif
 
+#ifdef HAVE_LINUX_TIPC_H
+       PyModule_AddIntConstant(m, "AF_TIPC", AF_TIPC);
+
+       /* for addresses */
+       PyModule_AddIntConstant(m, "TIPC_ADDR_NAMESEQ", TIPC_ADDR_NAMESEQ);
+       PyModule_AddIntConstant(m, "TIPC_ADDR_NAME", TIPC_ADDR_NAME);
+       PyModule_AddIntConstant(m, "TIPC_ADDR_ID", TIPC_ADDR_ID);
+
+       PyModule_AddIntConstant(m, "TIPC_ZONE_SCOPE", TIPC_ZONE_SCOPE);
+       PyModule_AddIntConstant(m, "TIPC_CLUSTER_SCOPE", TIPC_CLUSTER_SCOPE);
+       PyModule_AddIntConstant(m, "TIPC_NODE_SCOPE", TIPC_NODE_SCOPE);
+
+       /* for setsockopt() */
+       PyModule_AddIntConstant(m, "SOL_TIPC", SOL_TIPC);
+       PyModule_AddIntConstant(m, "TIPC_IMPORTANCE", TIPC_IMPORTANCE);
+       PyModule_AddIntConstant(m, "TIPC_SRC_DROPPABLE", TIPC_SRC_DROPPABLE);
+       PyModule_AddIntConstant(m, "TIPC_DEST_DROPPABLE",
+                       TIPC_DEST_DROPPABLE);
+       PyModule_AddIntConstant(m, "TIPC_CONN_TIMEOUT", TIPC_CONN_TIMEOUT);
+
+       PyModule_AddIntConstant(m, "TIPC_LOW_IMPORTANCE",
+                       TIPC_LOW_IMPORTANCE);
+       PyModule_AddIntConstant(m, "TIPC_MEDIUM_IMPORTANCE",
+                       TIPC_MEDIUM_IMPORTANCE);
+       PyModule_AddIntConstant(m, "TIPC_HIGH_IMPORTANCE",
+                       TIPC_HIGH_IMPORTANCE);
+       PyModule_AddIntConstant(m, "TIPC_CRITICAL_IMPORTANCE",
+                       TIPC_CRITICAL_IMPORTANCE);
+
+       /* for subscriptions */
+       PyModule_AddIntConstant(m, "TIPC_SUB_PORTS", TIPC_SUB_PORTS);
+       PyModule_AddIntConstant(m, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE);
+       PyModule_AddIntConstant(m, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL);
+       PyModule_AddIntConstant(m, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER);
+       PyModule_AddIntConstant(m, "TIPC_PUBLISHED", TIPC_PUBLISHED);
+       PyModule_AddIntConstant(m, "TIPC_WITHDRAWN", TIPC_WITHDRAWN);
+       PyModule_AddIntConstant(m, "TIPC_SUBSCR_TIMEOUT", TIPC_SUBSCR_TIMEOUT);
+       PyModule_AddIntConstant(m, "TIPC_CFG_SRV", TIPC_CFG_SRV);
+       PyModule_AddIntConstant(m, "TIPC_TOP_SRV", TIPC_TOP_SRV);
+#endif
+
        /* Socket types */
        PyModule_AddIntConstant(m, "SOCK_STREAM", SOCK_STREAM);
        PyModule_AddIntConstant(m, "SOCK_DGRAM", SOCK_DGRAM);
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index 95bc233..285c1fe 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -60,6 +60,10 @@
 # include <netpacket/packet.h>
 #endif
 
+#ifdef HAVE_LINUX_TIPC_H
+# include <linux/tipc.h>
+#endif
+
 #ifndef Py__SOCKET_H
 #define Py__SOCKET_H
 #ifdef __cplusplus
diff --git a/configure.in b/configure.in
index cdf1366..2ff6244 100644
--- a/configure.in
+++ b/configure.in
@@ -1107,7 +1107,7 @@ sys/param.h sys/poll.h sys/select.h sys/socket.h 
sys/statvfs.h sys/stat.h \
 sys/time.h \
 sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
 sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
-bluetooth/bluetooth.h)
+bluetooth/bluetooth.h linux/tipc.h)
 AC_HEADER_DIRENT
 AC_HEADER_MAJOR
 
-- 
1.5.4.rc2.1164.g6451


>From 156a6d71064c80af554b4097389347ad4d1b0196 Mon Sep 17 00:00:00 2001
From: Alberto Bertogli <[EMAIL PROTECTED]>
Date: Sun, 6 Jan 2008 16:20:00 -0200
Subject: [PATCH] Add documentation and Misc/NEWS entry for TIPC support.

---
 Doc/library/socket.rst |   27 +++++++++++++++++++++++++++
 Misc/NEWS              |    2 ++
 2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index 40e6d19..0e3aa19 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -66,6 +66,27 @@ numeric address in *host* portion.
 .. versionadded:: 2.5
    AF_NETLINK sockets are represented as  pairs ``pid, groups``.
 
+.. versionadded:: 2.6
+   Linux-only support for TIPC is also available using the :const:`AF_TIPC`
+   address family. TIPC is an open, non-IP based networked protocol designed
+   for use in clustered computer environments.  Addresses are represented by a
+   tuple, and the fields depend on the address type. The general tuple form is
+   ``(addr_type, v1, v2, v3 [, scope])``, where:
+
+     - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or
+       TIPC_ADDR_ID.
+     - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and
+       TIPC_NODE_SCOPE.
+     - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is
+       the port identifier, and *v3* should be 0.
+
+       If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2*
+       is the lower port number, and *v3* is the upper port number.
+
+       If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
+       reference, and *v3* should be set to 0.
+
+
 All errors raise exceptions.  The normal exceptions for invalid argument types
 and out-of-memory conditions can be raised; errors related to socket or address
 semantics raise the error :exc:`socket.error`.
@@ -169,6 +190,12 @@ The module :mod:`socket` exports the following constants 
and functions:
    
    .. versionadded:: 2.6
 
+.. data:: TIPC_*
+
+   TIPC related constants, matching the ones exported by the C socket API. See
+   the TIPC documentation for more information.
+
+   .. versionadded:: 2.6
 
 .. data:: has_ipv6
 
diff --git a/Misc/NEWS b/Misc/NEWS
index 4732113..719d448 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -342,6 +342,8 @@ Core and builtins
 Library
 -------
 
+- Issue #1646: Make socket support the TIPC protocol.
+
 - Bug #1742: return os.curdir from os.path.relpath() if both arguments are
   equal instead of raising an exception.
 
-- 
1.5.4.rc2.1164.g6451


>From f5a4dabd6cca72462ee5942a291bb2f91dd3850b Mon Sep 17 00:00:00 2001
From: Alberto Bertogli <[EMAIL PROTECTED]>
Date: Mon, 7 Jan 2008 07:18:11 -0200
Subject: [PATCH] Add unit tests for TIPC socket support.

---
 Lib/test/test_socket.py |   63 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 8f69a40..8ccdd8e 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1084,6 +1084,66 @@ class BufferIOTest(SocketConnectedTest):
         buf = buffer(MSG)
         self.serv_conn.send(buf)
 
+
+TIPC_STYPE = 2000
+TIPC_LOWER = 200
+TIPC_UPPER = 210
+
+class TIPCTest (unittest.TestCase):
+       def testRDM(self):
+               srv = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
+               cli = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
+
+               srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+               srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE,
+                               TIPC_LOWER, TIPC_UPPER)
+               srv.bind(srvaddr)
+
+               sendaddr = (socket.TIPC_ADDR_NAME, TIPC_STYPE,
+                               TIPC_LOWER + (TIPC_UPPER - TIPC_LOWER) / 2, 0)
+               cli.sendto(MSG, sendaddr)
+
+               msg, recvaddr = srv.recvfrom(1024)
+
+               self.assertEqual(cli.getsockname(), recvaddr)
+               self.assertEqual(msg, MSG)
+
+class TIPCThreadableTest (unittest.TestCase, ThreadableTest):
+       def __init__(self, methodName = 'runTest'):
+               unittest.TestCase.__init__(self, methodName = methodName)
+               ThreadableTest.__init__(self)
+
+       def setUp(self):
+               self.srv = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM)
+               self.srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+               srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE,
+                               TIPC_LOWER, TIPC_UPPER)
+               self.srv.bind(srvaddr)
+               self.srv.listen(5)
+               self.serverExplicitReady()
+               self.conn, self.connaddr = self.srv.accept()
+
+       def clientSetUp(self):
+               # The is a hittable race between serverExplicitReady() and the
+               # accept() call; sleep a little while to avoid it, otherwise
+               # we could get an exception
+               time.sleep(0.1)
+               self.cli = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM)
+               addr = (socket.TIPC_ADDR_NAME, TIPC_STYPE,
+                               TIPC_LOWER + (TIPC_UPPER - TIPC_LOWER) / 2, 0)
+               self.cli.connect(addr)
+               self.cliaddr = self.cli.getsockname()
+
+       def testStream(self):
+               msg = self.conn.recv(1024)
+               self.assertEqual(msg, MSG)
+               self.assertEqual(self.cliaddr, self.connaddr)
+
+       def _testStream(self):
+               self.cli.send(MSG)
+               self.cli.close()
+
+
 def test_main():
     tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest,
              TestExceptions, BufferIOTest, BasicTCPTest2]
@@ -1105,6 +1165,9 @@ def test_main():
         tests.append(BasicSocketPairTest)
     if sys.platform == 'linux2':
         tests.append(TestLinuxAbstractNamespace)
+    if hasattr(socket, "AF_TIPC"):
+        tests.append(TIPCTest)
+       tests.append(TIPCThreadableTest)
 
     thread_info = test_support.threading_setup()
     test_support.run_unittest(*tests)
-- 
1.5.4.rc2.1164.g6451


_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to