The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

IO::Socket::TIPC - TIPC sockets for Perl

SYNOPSIS

        use IO::Socket::TIPC;
        my $sock = IO::Socket::TIPC->new(
                SocketType => "stream",
                Peer       => "{1000, 100}"
        );
        die "Could not connect to {1000, 100}: $!\n" unless $sock;

More in-depth examples are available in the EXAMPLES section, below.

DESCRIPTION

TIPC stands for Transparent Inter-Process Communication. See http://tipc.sf.net/ for details.

This perl module subclasses IO::Socket, in order to use TIPC sockets in the customary (and convenient) Perl fashion.

TIPC supports 4 types of socket: SOCK_STREAM, SOCK_SEQPACKET, SOCK_RDM and SOCK_DGRAM. These are all available through this perl API, though the usage varies depending on which kind of socket you use.

SOCK_STREAM and SOCK_SEQPACKET are connection-based sockets. These sockets are strictly client/server. For servers, new() will call bind() for you, to bind to a Local* name, and you then accept() connections from clients, each of which get their own socket (returned from accept). For clients, new() will call connect() for you, to connect to the specified Peer* name, and once that succeeds, you can do I/O on the socket directly. In this respect, usage details are very similar to TCP over IPv4.

See the EXAMPLES section, for an example of connection-based socket use.

SOCK_RDM and SOCK_DGRAM are connectionless sockets. You cannot use the normal send/recv/print/getline methods on them, because the network stack will not know which host on the network to send or receive from. Instead, once you have called new() to create the socket, you use sendto and recvfrom to send and receive individual packets to/from a specified peer, indicated using an IO::Socket::TIPC::Sockaddr class object.

Connectionless sockets (SOCK_RDM and SOCK_DGRAM) are often bind()ed to a particular Name or Nameseq address, in order to allow them to listen for packets sent to a well-known destination (the Name). You can use LocalName or LocalNameseq parameters to new(), to select a name or name-sequence to bind to. As above, these parameters internally become Name and Nameseq arguments to IO::Socket::TIPC::Sockaddr->new(), and the result is passed to bind(). This is very similar to typical uses of UDP over IPv4.

Since connectionless sockets are not linked to a particular peer, you can use sendto to send a packet to some peer with a given Name in the network, and recvfrom to receive replies from a peer in the network who sends a packet to your Name (or Nameseq). You can also use Nameseq addressses to send multicast packets to *every* peer with a given name. Please see the Programmers_Guide.txt document (linked in REFERENCES) for more details.

See the EXAMPLES section, for an example of connection-less socket use.

CONSTRUCTOR

new returns a TIPC socket object. This object inherits from IO::Socket, and thus inherits all the methods of that class.

This module was modeled specifically after IO::Socket::INET, and shares some things in common with that class. Specifically, the Listen parameter, the Peer* and Local* nomenclature, and the behind-the-scenes calls to socket(), bind(), listen(), connect(), and so on.

Connection-based sockets (SOCK_STREAM and SOCK_SEQPACKET) come in "server" and "client" varieties. To create a server socket, specify the Listen argument to new(). You can bind a name to the socket, thus making your server easier to find, by providing one or more Local* parameters. To create a client socket, do NOT provide the Listen argument. Instead, provide one or more Peer* parameters, and new will call connect() for you.

All Local* parameters are passed directly to IO::Socket::TIPC::Sockaddr->new(), minus the "Local" prefix, and the resulting sockaddr is passed to bind(). Similarly, all Peer* parameters are passed directly to IO::Socket::TIPC::Sockaddr->new(), minus the "Peer" prefix, and the result is passed to connect(). The keywords Local and Peer themselves become the first string parameter to IO::Socket::TIPC::Sockaddr->new(); see the IO::Socket::TIPC::Sockaddr documentation for details.

ARGUMENTS to new()

SocketType

This field is required. It tells the system what type of socket to use. The following constants will work, if they were imported: SOCK_STREAM, SOCK_SEQPACKET, SOCK_RDM, or SOCK_DGRAM. Otherwise, you can just use the following text strings: "stream", "seqpacket", "rdm", or "dgram".

Listen

This field is only valid for connection-based SocketTypes. Its existence specifies that this is a server socket. It is common to also specify some Local* arguments, so new() can bind your shiny new server socket to a well-known name.

Importance

This field informs the TIPC network stack of what priority it should consider delivering your messages to be. It corresponds to the TIPC_IMPORTANCE option, from setsockopt. If you provide this field, ->new() will call setsockopt for you to set the value.

Default is TIPC_LOW_IMPORTANCE. Valid arguments are any of:

  TIPC_LOW_IMPORTANCE
  TIPC_MEDIUM_IMPORTANCE
  TIPC_HIGH_IMPORTANCE
  TIPC_CRITICAL_IMPORTANCE

See Programmers_Guide.txt (linked in REFERENCES) for details.

ConnectTimeout

This field specifies the connect() timeout, in milliseconds. If you provide this field, ->new() will call setsockopt to set the TIPC_CONN_TIMEOUT value on your socket.

See Programmers_Guide.txt (linked in REFERENCES) for details.

Careful: ConnectTimeout should not be confused with Timeout, which is handled internally by IO::Socket and means something else.

Local*

This field is valid (and recommended) for all connectionless socket types, and for all servers using connection-type sockets. The Local* parameter(s) determine which address your socket will get bind()ed to.

Any arguments prefixed with "Local" will be passed to IO::Socket::TIPC::Sockaddr->new(), with the "Local" prefix removed. If you specify the word Local, itself, the argument will be passed as the first string parameter to IO::Socket::TIPC::Sockaddr->new(); all other Local* arguments end up in the hash parameter list. See the documentation for IO::Socket::TIPC::Sockaddr, for details. Also, skip to the EXAMPLES section to see what this stuff looks like.

Peer*

This field is only valid for clients (as opposed to servers) using connection-type sockets, and is required for this case. The Peer* parameter(s) determine which address your socket will get connect()ed to.

Any arguments prefixed with "Peer" will be passed to IO::Socket::TIPC::Sockaddr->new(), with the "Peer" prefix removed. If you specify the word Peer, itself, the argument will be passed as the first string parameter to IO::Socket::TIPC::Sockaddr->new(); all other Peer* arguments end up in the hash parameter list. See the documentation for IO::Socket::TIPC::Sockaddr, for details. Also, skip to the EXAMPLES section to see what this stuff looks like.

METHODS

sendto(addr, message [, flags])

sendto is used with connectionless sockets, to send a message to a given address. The addr parameter should be an IO::Socket::TIPC::Sockaddr object.

        my $addr = IO::Socket::TIPC::Sockaddr->new("{4242, 100}");
        $sock->sendto($addr, "Hello there!\n");

The third parameter, flags, defaults to 0 when not specified. The TIPC Programmers_Guide.txt says: "TIPC supports the MSG_DONTWAIT flag when sending; all other flags are ignored."

You may have noticed that sendto and the send builtin do more or less the same thing with the order of arguments changed. The main reason to use sendto is because you can pass it a IO::Socket::TIPC::Sockaddr object directly, where send requires you to dereference the blessed reference to get at the raw binary "struct sockaddr_tipc" bits. So, sendto is just a matter of convenience.

Ironically, this sendto method calls the send builtin, which in turn calls the C sendto function.

recvfrom(buffer [, length [, flags]])

recvfrom is used with connectionless sockets, to receive a message from a peer. It returns a IO::Socket::TIPC::Sockaddr object, containing the address of whoever sent the message. It will write the received packet (up to $length bytes) in $buffer.

        my $buffer;
        my $sender = $sock->recvfrom($buffer, 30);
        $sock->sendto($sender, "I got your message.");

The second parameter, length, defaults to TIPC_MAX_USER_MSG_SIZE when not specified. The third parameter, flags, defaults to 0 when not specified.

The TIPC Programmers_Guide.txt says: "TIPC supports the MSG_PEEK flag when receiving, as well as the MSG_WAITALL flag when receiving on a SOCK_STREAM socket; all other flags are ignored."

You may have noticed that recvfrom and the recv builtin do more or less the same thing with the order of arguments changed. The main reason to use recvfrom is because it will return a IO::Socket::TIPC::Sockaddr object, where recv just returns a binary blob containing the C "struct sockaddr_tipc" data, which, by itself, cannot be inspected or modified. So, recvfrom is just a matter of convenience.

Ironically, this recvfrom method calls the recv builtin, which in turn calls the C recvfrom function.

bind(addr)

bind attaches a well-known "name" to an otherwise random (and hard to find) socket port. It is possible to bind more than one name to a socket. bind is useful for all connectionless sockets, and for "server" sockets (the one you get from new(Listen => 1), not the ones returned from accept).

This method is really just a wrapper around the Perl bind builtin, which dereferences IO::Socket::TIPC::Sockaddr class instances when necessary.

connect(addr)

connect seeks out a server socket (which was binded to a well-known "name") and connects to it. connect is only valid for connection-type sockets which have not already had listen or bind called on them. In practice, you should not ever need this method; new calls it for you when you specify one or more Peer arguments.

This method is really just a wrapper around the Perl connect builtin, which dereferences IO::Socket::TIPC::Sockaddr class instances when necessary.

getpeername

getpeername returns the sockaddr of the peer you're connected to. Compare getsockname. Use this if you've just accept()ed a new connection, and you're curious who you're talking to.

        my $client = $server->accept();
        my $caddr = $client->getpeername();
        print("Got connection from ", $caddr->stringify(), "\n");

getpeername doesn't actually return a name sockaddr, it returns an id. Thus, getpeerid is an alias for getpeername, to aid readability. Programmers_Guide.txt has the following comment: The use of "name" in getpeername() can be confusing, as the routine does not actually return the TIPC names or name sequences that have been bound to the peer socket.

This method is really just a wrapper around the Perl getpeername builtin, to wrap return values into IO::Socket::TIPC::Sockaddr class instances for you.

getsockname

getsockname returns the sockaddr of your own socket, this is the address your peer sees you coming from. Compare getpeername.

        my $client = $server->accept();
        my $caddr = $client->getsockname();
        print("The client connected to me as ", $caddr->stringify(), "\n");

getsockname doesn't actually return a name sockaddr, it returns an id. Thus, getsockid is an alias for getsockname, to aid readability. Programmers_Guide.txt has the following comment: The use of "name" in getsockname() can be confusing, as the routine does not actually return the TIPC names or name sequences that have been bound to the peer socket.

This method is really just a wrapper around the Perl getsockname builtin, to wrap return values into IO::Socket::TIPC::Sockaddr class instances for you.

listen

listen tells the operating system that this is a server socket, and that you will be accept()ing client connections on it. It is only valid for connection-type sockets, and only if connect has not been called on it. It is much more useful if you have binded the socket to a well-known name; otherwise, most clients will have difficulty knowing what to connect to.

This module does not actually implement a listen method; when you call it, you are really just calling the Perl builtin. See the perlfunc manpage for more details.

accept

accept asks the operating system to return a session socket, for communicating with a client which has just connected to you. It is only valid for connection-type sockets, which you have previously called listen on.

This module does not actually implement an accept method; when you call it, you are really just calling the Perl builtin. See the perlfunc manpage for more details.

getsockopt(level, optname)

Query a socket option. For TIPC-level stuff, level should be SOL_TIPC.

The TIPC Programmers_Guide.txt (linked in REFERENCES) says: - TIPC does not currently support socket options for level SOL_SOCKET, such as SO_SNDBUF. - TIPC does not currently support socket options for level IPPROTO_TCP, such as TCP_MAXSEG. Attempting to get the value of these options on a SOCK_STREAM socket returns the value 0.

See setsockopt(), below, for a list of SOL_TIPC options.

This module does not actually implement a getsockopt method; when you call it, you are really just calling the Perl builtin. See the perlfunc manpage for more details.

setsockopt(level, optname, optval)

Set a socket option. For TIPC-level stuff, level should be SOL_TIPC.

The TIPC Programmers_Guide.txt (linked in REFERENCES) says: - TIPC does not currently support socket options for level SOL_SOCKET, such as SO_SNDBUF. - TIPC does not currently support socket options for level IPPROTO_TCP, such as TCP_MAXSEG. Attempting to get the value of these options on a SOCK_STREAM socket returns the value 0.

For level SOL_TIPC, the following options are available:

        TIPC_IMPORTANCE
        TIPC_SRC_DROPPABLE
        TIPC_DEST_DROPPABLE
        TIPC_CONN_TIMEOUT

These are documented in detail in Programmers_Guide.txt. See also, ->new()'s Importance and ConnectTimeout options.

This module does not actually implement a setsockopt method; when you call it, you are really just calling the Perl builtin. See the perlfunc manpage for more details.

detect()

detect determines whether TIPC is usable on your system. It will return a true value if it detects TIPC support has been loaded into your operating system kernel, and will return 0 otherwise.

EXAMPLES

Examples of connection-based socket use:

        # SERVER PROCESS
        # create a server listening on Name {4242, 100}.
        $sock1 = IO::Socket::TIPC->new(
                SocketType => "seqpacket",
                Listen => 1,
                Local => "{4242, 100}",
                LocalScope => "zone",
        );
        $client = $sock1->accept();
        # Wait for the client to say something intelligent
        $something_intelligent = $client->getline();


        # CLIENT PROCESS
        # connect to the above server
        $sock2 = IO::Socket::TIPC->new(
                SocketType => "seqpacket",
                Peer => "{4242, 100}",
        );
        # Say something intelligent
        $sock2->print("Dah, he is Olle, you are Sven.\n");
        

Examples of connectionless socket use:

        # NODE 1
        # Create a server listening on Name {4242, 101}.
        $sock1 = IO::Socket::TIPC->new(
                SocketType => "rdm",
                Local => "{4242, 101}",
                LocalScope => "zone",
        );
        $data = "TAG!  You are \"it\".\n";
        # send a hello packet from sock1 to sock2
        $addr2 = IO::Socket::TIPC::Sockaddr->new("{4242, 102}");
        $sock1->sendto($addr2, $data);


        # NODE 2
        # Create another server listening on Name {4242, 102}.
        $sock2 = IO::Socket::TIPC->new(
                SocketType => "rdm",
                Local => "{4242, 102}",
                LocalScope => "zone",
        );
        # receive that first hello packet
        $sender = $sock2->recvfrom($rxdata, 256);
        # Reply
        $sock2->sendto($sender, "Me too.\n");
        
        # send a multicast packet to all sock1s in the world
        $maddr1 = IO::Socket::TIPC::Sockaddr->new("{4242,101,101}");
        $sock2->sendto($maddr2, "My brain hurts!\n");

EXPORT

None by default.

Exportable constants and macros

  ":tipc" tag (defines from tipc.h, loosely grouped by function):
  AF_TIPC, PF_TIPC, SOL_TIPC
  TIPC_ADDR_ID, TIPC_ADDR_MCAST, TIPC_ADDR_NAME, TIPC_ADDR_NAMESEQ
  TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, TIPC_NODE_SCOPE
  TIPC_ERRINFO, TIPC_RETDATA, TIPC_DESTNAME
  TIPC_IMPORTANCE, TIPC_SRC_DROPPABLE, TIPC_DEST_DROPPABLE,
  TIPC_CONN_TIMEOUT
  TIPC_LOW_IMPORTANCE, TIPC_MEDIUM_IMPORTANCE, TIPC_HIGH_IMPORTANCE,
  TIPC_CRITICAL_IMPORTANCE
  TIPC_MAX_USER_MSG_SIZE
  TIPC_OK, TIPC_ERR_NO_NAME, TIPC_ERR_NO_NODE, TIPC_ERR_NO_PORT,
  TIPC_ERR_OVERLOAD, TIPC_CONN_SHUTDOWN  
  TIPC_PUBLISHED, TIPC_WITHDRAWN, TIPC_SUBSCR_TIMEOUT
  TIPC_SUB_NO_BIND_EVTS, TIPC_SUB_NO_UNBIND_EVTS,
  TIPC_SUB_PORTS, TIPC_SUB_SERVICE, TIPC_SUB_SINGLE_EVT
  TIPC_CFG_SRV, TIPC_TOP_SRV, TIPC_RESERVED_TYPES
  TIPC_WAIT_FOREVER
  tipc_addr, tipc_zone, tipc_cluster, tipc_node

(Those last 4 are re-exports from the Sockaddr module. See the IO::Socket::TIPC::Sockaddr documentation.)

  ":sock" tag (re-exports from IO::Socket):
  SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RDM
  MSG_DONTWAIT, MSG_PEEK, MSG_WAITALL, MSG_CTRUNC

To get all of the above constants, say:

  use IO::Socket::TIPC ":all";

To get all of the tipc stuff, say:

  use IO::Socket::TIPC ":tipc";

To get only the socket stuff, say:

  use IO::Socket::TIPC ":sock";

To get only the constants you plan to use, say something like:

  use IO::Socket::TIPC qw(SOCK_RDM TIPC_NODE_SCOPE TIPC_ADDR_NAMESEQ);

Despite supporting all the above constants, please note that some effort was made so normal users will never actually need any of them. For instance, in place of the SOCK_* socktypes, you can just specify "stream", "dgram", "seqpacket" or "rdm". In place of the TIPC_*_SCOPE defines, given to IO::Socket::TIPC::Sockaddr->new() as the Scope parameter, you can simply say "zone", "cluster" or "node".

BUGS

Probably many. Please report any bugs you find to the author. A TODO file exists, which lists known unimplemented and broken stuff.

REFERENCES

See also:

IO::Socket, IO::Socket::TIPC::Sockaddr, http://tipc.sf.net/.

The Programmers_Guide.txt is particularly helpful, and is available off the SourceForge site. See http://tipc.sf.net/doc/Programmers_Guide.txt, or http://tipc.sf.net/documentation.html.

AUTHOR

Mark Glines <mark-tipc@glines.org>

ACKNOWLEDGEMENTS

Thanks to Ericcson and Wind River, of course, for open-sourcing their (very useful!) network code, and performing the enormous maintenance task of getting it into the stock Linux kernel. Respect.

More specifically, thanks to the TIPC maintainers, for doing all the work bringing TIPC to linux, and making all of this possible. And thanks especially to Allan Stephens for patiently testing all of my pathetic, bug-ridden alpha releases. :)

Thanks to Renaud Metrich and Sun Microsystems for bringing TIPC to Solaris, and testing even more of my pathetic, bug-ridden patches.

COPYRIGHT AND LICENSE

This module is licensed under a dual BSD/GPL license, the same terms as TIPC itself.