From: Alberto B. <alb...@gm...> - 2007-12-16 14:15:16
|
Hi! I needed a way to use TIPC inside Python for work, and since I couldn't find any, I wrote a small module that provides TIPC sockets with a similar interface to the one provided by the official socket module. You can find it at http://auriga.wearlab.de/~alb/pytipc/ and you can browse the repository and the files at http://repo.or.cz/w/pytipc.git. I also wrote a patch for the official socket module, which I will post soon. Thanks a lot, Alberto |
From: Alberto B. <alb...@gm...> - 2007-12-16 16:32:19
Attachments:
0002-Make-socket-support-TIPC.patch
|
On Sat, Dec 15, 2007 at 04:13:23PM -0300, Alberto Bertogli wrote: > I also wrote a patch for the official socket module, which I will post > soon. Here's the patch for the Python's socket module. If it's ok with you, intend to send it to the python's development mailing list; so it'd be great if somebody with more TIPC experience than myself reviews it. The patch itself it's quite simple: it adds some TIPC constants at the end, and adds a way to convert a struct sockaddr_tipc into a Python tuple, and viceversa. The tuple is composed of four integer values: - TIPC_ADDR_NAME or TIPC_ADDR_NAMESEQ - A server type if TIPC_ADDR_NAME: - A port number - Ignored else: - Lower port number - Upper port number The scope is hardcoded to cluster; but if you think it's worth it, I can make it to be an optional fifth value. If this patch gets applied, it will be extremely hard to change the address representation in the future, so it'd be nice to get it right =) I selected a tuple because it is: - a simple, easy to construct data structure, - extensible if we need to add more fields in the future, - used as a way to express addresses for all the other network protocols. I know there are two more address types (TIPC_ADDR_MCAST and TIPC_ADDR_ID), but I have never used them, so I don't know the semantics well enough. .From the tipc examples I can assume TIPC_ADDR_MCAST uses nameseq and TIPC_ADDR_ID uses the id part of the sockaddr_tipc union. If you think it's worth it, I can add code to handle those too (they will fit into the 4-tuple described above). Thanks a lot, Alberto |
From: Alberto B. <alb...@gm...> - 2007-12-17 19:30:46
Attachments:
0002-Make-socket-support-TIPC.patch
|
On Sun, Dec 16, 2007 at 01:20:44PM -0300, Alberto Bertogli wrote: > I know there are two more address types (TIPC_ADDR_MCAST and > TIPC_ADDR_ID), but I have never used them, so I don't know the > semantics well enough. I've added support for those two address types, and an optional fifth tuple element for the socket scope. The following patch is an updated version of the previous one containing these changes. Thanks a lot, Alberto |
From: Jon P. M. <jon...@er...> - 2007-12-17 20:41:10
|
I don't know much about Python, but it looks ok to me, according to your description. Yo may have noticed that TIPC_ADDR_NAMESEQ and TIPC_ADDR_MCAST in reality indicates the same address type, i.e. they have the same value. Maybe that will simplify your code a little ? Regards ///jon Alberto Bertogli wrote: > On Sun, Dec 16, 2007 at 01:20:44PM -0300, Alberto Bertogli wrote: > >> I know there are two more address types (TIPC_ADDR_MCAST and >> TIPC_ADDR_ID), but I have never used them, so I don't know the >> semantics well enough. >> > > I've added support for those two address types, and an optional fifth > tuple element for the socket scope. > > The following patch is an updated version of the previous one containing > these changes. > > Thanks a lot, > Alberto > > > ------------------------------------------------------------------------ > > From: Alberto Bertogli <alb...@gm...> > 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 | 156 +++++++++++++++++++++++++++++++++++++++++++++++- > Modules/socketmodule.h | 4 + > configure.in | 2 +- > 3 files changed, 160 insertions(+), 2 deletions(-) > > diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c > --- 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_MCAST, 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 or TIPC_ADDR_MCAST: > + 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,40 @@ 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 || > + a->addrtype == TIPC_ADDR_MCAST) { > + 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 +1433,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 || atype == TIPC_ADDR_MCAST) { > + 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 +1568,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: > @@ -4419,6 +4531,48 @@ 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_MCAST", TIPC_ADDR_MCAST); > + 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 > --- a/Modules/socketmodule.h > +++ b/Modules/socketmodule.h > @@ -59,6 +59,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 > --- a/configure.in > +++ b/configure.in > @@ -1106,7 +1106,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 > > > ------------------------------------------------------------------------ > > ------------------------------------------------------------------------- > SF.Net email is sponsored by: > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services > for just about anything Open Source. > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > ------------------------------------------------------------------------ > > _______________________________________________ > tipc-discussion mailing list > tip...@li... > https://lists.sourceforge.net/lists/listinfo/tipc-discussion > |
From: Alberto B. <alb...@gm...> - 2007-12-17 21:27:09
|
On Mon, Dec 17, 2007 at 03:40:59PM -0500, Jon Paul Maloy wrote: > I don't know much about Python, but it looks ok > to me, according to your description. Thanks! > Yo may have noticed that TIPC_ADDR_NAMESEQ > and TIPC_ADDR_MCAST in reality indicates the same > address type, i.e. they have the same value. > > Maybe that will simplify your code a little ? I actually haven't noticed! It doesn't simplify the code much, as I already support NAMESEQ, but it simplifies the conditionals a bit. Unless anybody has an objection (e.g. it shouldn't be used in new code anymore), I think I'll leave the constant exported just in case somebody is attached to it, because the benefit of removing it is really small, but add a small notice in the documentation about it being the same as NAMESEQ. Thanks, Alberto |