]> git.llucax.com Git - software/posixx.git/blob - src/linux/tipc.hpp
Fix tipc::sockaddr::operator == ()
[software/posixx.git] / src / linux / tipc.hpp
1 #ifndef POSIXX_LINUX_TIPC_HPP_
2 #define POSIXX_LINUX_TIPC_HPP_
3
4 #include "../socket/basic_socket.hpp" // posixx::socket
5
6 #include <linux/tipc.h> // all tipc stuff
7 #include <cstring> // memcpy
8
9 /// @file
10
11 namespace posixx {
12
13 /// Linux specific functionality
14 namespace linux {
15
16 /// TIPC socket domain.
17 namespace tipc {
18
19 enum
20 {
21         /// Configuration port name.
22         CFG_SRV = TIPC_CFG_SRV,
23         /// Topology discovery port name.
24         TOP_SRV = TIPC_TOP_SRV,
25         /// Name of the last reserved port.
26         RESERVED_TYPES = TIPC_RESERVED_TYPES,
27         /// Maximum message size.
28         MAX_USER_MSG_SIZE = TIPC_MAX_USER_MSG_SIZE,
29         /// Wait forever (for subscriptions).
30         WAIT_FOREVER = TIPC_WAIT_FOREVER
31 };
32
33 /// TIPC Address
34 struct addr
35 {
36
37         /// 32-bit address.
38         __u32 address;
39
40         /// Constructor
41         addr() throw ();
42
43         /**
44          * Constructor from a raw 32-bit address.
45          *
46          * @param addr Raw 32-bit address.
47          */
48         explicit addr(__u32 addr) throw ();
49
50         /**
51          * Constructor from a zone, cluster and node information.
52          *
53          * @param zone Zone.
54          * @param cluster Cluster.
55          * @param node Node.
56          */
57         addr(unsigned int zone, unsigned int cluster, unsigned int node)
58                 throw ();
59
60         /// Set zone.
61         void zone(unsigned int zone) throw ();
62
63         /// Get zone.
64         unsigned int zone() const throw ();
65
66         /// Set cluster.
67         void cluster(unsigned int cluster) throw ();
68
69         /// Get cluster.
70         unsigned int cluster() const throw ();
71
72         /// Set node.
73         void node(unsigned int node) throw ();
74
75         /// Get node.
76         unsigned int node() const throw ();
77
78         /// Cast to a raw 32-bit address.
79         operator __u32 () const throw ();
80
81 };
82
83 /**
84  * Port Identificator.
85  *
86  * @see tipc_portid struct from linux/tipc.h.
87  */
88 struct portid: tipc_portid
89 {
90
91         /**
92          * Constructor.
93          *
94          * @param ref Unique ID fo the port in the address.
95          * @param node Node address.
96          */
97         portid(__u32 ref, addr node) throw ();
98
99         /// Access to the node addr.
100         addr& node_addr() throw ();
101
102         /// Access to the node addr.
103         const addr& node_addr() const throw ();
104
105         /// Compares 2 port ids.
106         bool operator == (const portid& other) const throw ();
107
108 };
109
110 /**
111  * Named port.
112  *
113  * @see tipc_name struct from linux/tipc.h.
114  */
115 struct name: tipc_name
116 {
117
118         /**
119          * Constructor.
120          *
121          * @param type Type of the named port.
122          * @param instance Instance of the named port.
123          */
124         name(__u32 type, __u32 instance) throw ();
125
126         /// Compares 2 port names.
127         bool operator == (const name& other) const throw ();
128
129 };
130
131 /**
132  * Port sequence.
133  *
134  * @see tipc_name_seq struct from linux/tipc.h.
135  */
136 struct nameseq: tipc_name_seq
137 {
138
139         /**
140          * Constructor.
141          *
142          * @param type Type of the sequence.
143          * @param lower Lower bound.
144          * @param upper Upper bound.
145          */
146
147         nameseq(__u32 type, __u32 lower, __u32 upper) throw ();
148         /**
149          * Constructor.
150          *
151          * @param type Type of the sequence.
152          * @param instance Lower and upper bound.
153          */
154         nameseq(__u32 type, __u32 instance) throw ();
155
156         /// Compares 2 port name sequences.
157         bool operator == (const nameseq& other) const throw ();
158
159 };
160
161 /**
162  * Reasons for returned messages when recvmsg() is used.
163  *
164  * @see recvmsg(2) of TIPC documentation
165  */
166 enum reason_t
167 {
168         /// Not a returned message.
169         OK = TIPC_OK,
170         /// Port name doesn't exist.
171         ERR_NO_NAME = TIPC_ERR_NO_NAME,
172         /// Port ID doesn't exist.
173         ERR_NO_PORT = TIPC_ERR_NO_PORT,
174         /// Node doesn't exist.
175         ERR_NO_NODE = TIPC_ERR_NO_NODE,
176         /// Reception queue is full.
177         ERR_OVERLOAD = TIPC_ERR_OVERLOAD,
178         /// Connection shutted down.
179         CONN_SHUTDOWN = TIPC_CONN_SHUTDOWN
180 };
181
182 /**
183  * Subscription filter type.
184  *
185  * @see TIPC documentation: 1.4.3 Name Subscriptions
186  */
187 enum subscr_t
188 {
189
190         /**
191          * Causes the topology service to generate a PUBLISHED event
192          * for each port name or port name sequence it finds that overlaps
193          * the specified port name sequence; a WITHDRAWN event is issued
194          * each time a previously reported name becomes unavailable.
195          *
196          * Allows the topology service to inform the application if there
197          * are @b any ports of interest.
198          */
199         SUB_PORTS = TIPC_SUB_PORTS,
200
201         /**
202          * Causes the topology service to generate a single publish event for
203          * the first port it finds with an overlapping name and a single
204          * withdraw event when the last such port becomes unavailable.
205          *
206          * Allows the topology service to inform the application about
207          * @b all ports of interest.
208          */
209         SUB_SERVICE = TIPC_SUB_SERVICE,
210
211         /**
212          * Instruct the topology service to cancel a previously requested
213          * subscription.
214          *
215          * The application simply resends the original subscription request
216          * with SUB_CANCEL logically OR'd into the event filter.
217          *
218          * @note This is implemented in TIPC 1.7+ only (according to TIPC
219          *       documentation).
220          */
221         SUB_CANCEL = TIPC_SUB_CANCEL
222
223 };
224
225 /**
226  * Subscription request message.
227  *
228  * @see TIPC documentation: 1.4.3 Name Subscriptions
229  */
230 struct subscr: tipc_subscr
231 {
232
233         /**
234          * Constructor.
235          *
236          * @param seq The port name sequence of interest to the application.
237          * @param timeout A subscription timeout value, in ms
238          *                (or WAIT_FOREVER).
239          * @param filter An event filter specifying which events are of
240          *               interest to the application (see subscr_t).
241          * @param usr_handle An 8 byte user handle that is application-defined,
242          *                   (treated as a string).
243          */
244         subscr(nameseq seq, __u32 timeout, __u32 filter,
245                         const char* usr_handle = "") throw ();
246
247         /**
248          * Constructor.
249          *
250          * @param seq The port name sequence of interest to the application.
251          * @param timeout A subscription timeout value, in ms
252          *                (or WAIT_FOREVER).
253          * @param filter An event filter specifying which events are of
254          *               interest to the application (see subscr_t).
255          * @param usr_handle An 8 byte user handle that is application-defined.
256          *                   (treated as binary data).
257          * @param handle_size Size of the usr_handle buffer (it should be at
258          *                    most 8)
259          */
260         subscr(nameseq seq, __u32 timeout, __u32 filter,
261                         const char* usr_handle, size_t handle_size)
262                         throw ();
263
264         /// Access to the subscribed name sequence.
265         nameseq& name_seq() throw ();
266
267         /// Access to the subscribed name sequence.
268         const nameseq& name_seq() const throw ();
269
270         /// Set the user handle as a string.
271         void handle(const char* usr_handle) throw ();
272
273         /// Set the user handle as binary data.
274         void handle(const char* usr_handle, size_t handle_size) throw ();
275
276         /// Compares 2 subscription request messages.
277         bool operator == (const subscr& other) const throw ();
278
279 };
280
281 /// Type of events.
282 enum event_t
283 {
284
285         /// The port has been published.
286         PUBLISHED = TIPC_PUBLISHED,
287
288         /// The port has been withdrawn.
289         WITHDRAWN = TIPC_WITHDRAWN,
290
291         /// The event has timed out.
292         TIMEOUT = TIPC_SUBSCR_TIMEOUT
293
294 };
295
296 /**
297  * Event message.
298  *
299  * @see TIPC documentation: 1.4.3 Name Subscriptions
300  */
301 struct subscr_event: tipc_event
302 {
303
304         /// Access to the subscribed name sequence.
305         portid& port_id() throw ();
306
307         /// Access to the subscribed name sequence.
308         const portid& port_id() const throw ();
309
310         /// Access to the subscribed name sequence.
311         subscr& subscription() throw ();
312
313         /// Access to the subscribed name sequence.
314         const subscr& subscription() const throw ();
315
316 };
317
318 /**
319  * TIPC socket address (name).
320  *
321  * @see bind(2), Socket::bind()
322  * @see connect(2), Socket::connect()
323  * @see getsockaddr(2), Socket::getsockaddr()
324  * @see setsockaddr(2), Socket::setsockaddr()
325  * @see accept(2), Socket::accept()
326  * @see sendto(2), Socket::send()
327  * @see recvfrom(2), Socket::recv()
328  */
329 struct sockaddr: sockaddr_tipc
330 {
331
332         /// Type of TIPC address
333         enum type_t
334         {
335                 ID = TIPC_ADDR_ID, ///< Port ID
336                 NAME = TIPC_ADDR_NAME, ///< Port name
337                 NAMESEQ = TIPC_ADDR_NAMESEQ ///< Name sequence or multicast
338         };
339
340         /**
341          * Bind scope.
342          *
343          * @see TIPC documentation: 2.1.2 bind
344          */
345         enum scope_t
346         {
347                 ZONE = TIPC_ZONE_SCOPE,       ///< Zone scope.
348                 CLUSTER = TIPC_CLUSTER_SCOPE, ///< Cluster scope.
349                 NODE = TIPC_NODE_SCOPE        ///< Node scope.
350         };
351
352         /// Constructor.
353         sockaddr() throw ();
354
355         /**
356          * Constructor using a port ID.
357          *
358          * @param port Port ID.
359          * @param scope Bind scope.
360          */
361         sockaddr(portid port, scope_t scope = ZONE) throw ();
362
363         /**
364          * Constructor using a port name.
365          *
366          * @param name Port name.
367          * @param scope Bind scope.
368          * @param domain Domain lookup.
369          *
370          * @see Documentación de TIPC: 1.4.1 Address Resolution
371          */
372         sockaddr(name name, scope_t scope = ZONE,
373                         tipc::addr domain = tipc::addr(0u))
374                 throw ();
375
376         /**
377          * Constructor using a port name sequence.
378          *
379          * @param nameseq Port name sequence.
380          * @param scope Bind scope.
381          */
382         sockaddr(nameseq nameseq, scope_t scope = ZONE) throw ();
383
384         /// Type of TIPC address
385         type_t type() const throw ();
386
387         /// Length of this unix socket address
388         socklen_t length() const throw ();
389
390         /// Compare two TIPC socket addresses
391         bool operator == (const sockaddr& other) const throw ();
392
393         /// Access to the port ID (only valid if addrtype == ID)
394         portid& port_id() throw ();
395
396         /// Access to the port ID (only valid if addrtype == ID)
397         const portid& port_id() const throw ();
398
399         /// Access to the port name (only valid if addrtype == NAME)
400         name& port_name() throw ();
401
402         /// Access to the port name (only valid if addrtype == NAME)
403         const name& port_name() const throw ();
404
405         /// Access to the port name domain (only valid if addrtype == NAME)
406         tipc::addr& name_domain() throw ();
407
408         /// Access to the port name domain (only valid if addrtype == NAME)
409         const tipc::addr& name_domain() const throw ();
410
411         /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
412         nameseq& name_seq() throw ();
413
414         /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
415         const nameseq& name_seq() const throw ();
416
417 };
418
419 /// TIPC socket traits.
420 struct traits
421 {
422
423         /// Socket address type.
424         typedef tipc::sockaddr sockaddr;
425
426         /// Protocol family.
427         enum { PF = PF_TIPC };
428
429 };
430
431 /// TIPC socket
432 typedef posixx::socket::basic_socket< traits > socket;
433
434 } } } // namespace posixx::linux::tipc
435
436
437 inline
438 posixx::linux::tipc::addr::addr() throw (): address(0u)
439 {
440 }
441
442 inline
443 posixx::linux::tipc::addr::addr(__u32 address) throw (): address(address)
444 {
445 }
446
447 inline
448 posixx::linux::tipc::addr::addr(unsigned int zone, unsigned int cluster,
449                 unsigned int node) throw ():
450         address(tipc_addr(zone, cluster, node))
451 {
452 }
453
454 inline
455 void posixx::linux::tipc::addr::zone(unsigned int zone) throw ()
456 {
457         address = tipc_addr(zone, cluster(), node());
458 }
459
460 inline
461 unsigned int posixx::linux::tipc::addr::zone() const throw ()
462 {
463         return tipc_zone(address);
464 }
465
466 inline
467 void posixx::linux::tipc::addr::cluster(unsigned int cluster) throw ()
468 {
469         address = tipc_addr(zone(), cluster, node());
470 }
471
472 inline
473 unsigned int posixx::linux::tipc::addr::cluster() const throw ()
474 {
475         return tipc_cluster(address);
476 }
477
478 inline
479 void posixx::linux::tipc::addr::node(unsigned int node) throw ()
480 {
481         address = tipc_addr(zone(), cluster(), node);
482 }
483
484 inline
485 unsigned int posixx::linux::tipc::addr::node() const throw ()
486 {
487         return tipc_node(address);
488 }
489
490 inline
491 posixx::linux::tipc::addr::operator __u32 () const throw ()
492 {
493         return address;
494 }
495
496 inline
497 posixx::linux::tipc::portid::portid(__u32 r, addr n) throw ()
498 {
499         ref = r;
500         node = n;
501 }
502
503 inline
504 posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() throw ()
505 {
506         return *reinterpret_cast<addr*>(&node);
507 }
508
509 inline
510 const posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() const
511                 throw ()
512 {
513         return *reinterpret_cast<const addr*>(&node);
514 }
515
516 inline
517 bool posixx::linux::tipc::portid::operator == (
518                 const posixx::linux::tipc::portid& other) const throw ()
519 {
520         return memcmp(this, &other, sizeof(*this)) == 0;
521 }
522
523 inline
524 posixx::linux::tipc::name::name(__u32 t, __u32 i) throw ()
525 {
526         type = t;
527         instance = i;
528 }
529
530 inline
531 bool posixx::linux::tipc::name::operator == (
532                 const posixx::linux::tipc::name& other) const throw ()
533 {
534         return memcmp(this, &other, sizeof(*this)) == 0;
535 }
536
537 inline
538 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 low, __u32 up) throw ()
539 {
540         type = t;
541         lower = low;
542         upper = up;
543 }
544
545 inline
546 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 instance) throw ()
547 {
548         type = t;
549         lower = instance;
550         upper = instance;
551 }
552
553 inline
554 bool posixx::linux::tipc::nameseq::operator == (
555                 const posixx::linux::tipc::nameseq& other) const throw ()
556 {
557         return memcmp(this, &other, sizeof(*this)) == 0;
558 }
559
560 inline
561 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
562                 const char* uh) throw ()
563 {
564         seq = s;
565         timeout = t;
566         filter = f;
567         handle(uh);
568 }
569
570 inline
571 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
572                 const char* uh, size_t uh_size) throw ()
573 {
574         seq = s;
575         timeout = t;
576         filter = f;
577         handle(uh, uh_size);
578 }
579
580 inline
581 posixx::linux::tipc::nameseq& posixx::linux::tipc::subscr::name_seq() throw ()
582 {
583         return *reinterpret_cast<nameseq*>(&seq);
584 }
585
586 inline
587 const posixx::linux::tipc::nameseq&
588 posixx::linux::tipc::subscr::name_seq() const throw ()
589 {
590         return *reinterpret_cast<const nameseq*>(&seq);
591 }
592
593 inline
594 void posixx::linux::tipc::subscr::handle(const char* uh) throw ()
595 {
596         std::strncpy(usr_handle, uh, sizeof(usr_handle));
597 }
598
599 inline
600 void posixx::linux::tipc::subscr::handle(const char* uh, size_t uh_size)
601                 throw ()
602 {
603         std::memcpy(usr_handle, uh, uh_size);
604 }
605
606 inline
607 bool posixx::linux::tipc::subscr::operator == (const subscr& other) const
608                 throw ()
609 {
610         return memcmp(this, &other, sizeof(*this)) == 0;
611 }
612
613 inline
614 posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
615                 throw ()
616 {
617         return *reinterpret_cast<portid*>(&port);
618 }
619
620 inline
621 const posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
622                 const throw ()
623 {
624         return *reinterpret_cast<const portid*>(&port);
625 }
626
627 inline
628 posixx::linux::tipc::subscr& posixx::linux::tipc::subscr_event::subscription()
629                 throw ()
630 {
631         return *reinterpret_cast<subscr*>(&s);
632 }
633
634 inline
635 const posixx::linux::tipc::subscr&
636 posixx::linux::tipc::subscr_event::subscription() const throw ()
637 {
638         return *reinterpret_cast<const subscr*>(&s);
639 }
640
641 inline
642 posixx::linux::tipc::sockaddr::sockaddr() throw ()
643 {
644 }
645
646 inline
647 posixx::linux::tipc::sockaddr::sockaddr(portid port, scope_t s) throw ()
648 {
649         family = AF_TIPC;
650         addrtype = TIPC_ADDR_ID;
651         scope = s;
652         addr.id = port;
653 }
654
655 inline
656 posixx::linux::tipc::sockaddr::sockaddr(name name, scope_t s, tipc::addr d)
657                 throw ()
658 {
659         family = AF_TIPC;
660         addrtype = TIPC_ADDR_NAME;
661         scope = s;
662         addr.name.name = name;
663         addr.name.domain = d;
664 }
665
666 inline
667 posixx::linux::tipc::sockaddr::sockaddr(nameseq nameseq, scope_t s) throw ()
668 {
669         family = AF_TIPC;
670         addrtype = TIPC_ADDR_NAMESEQ;
671         scope = s;
672         addr.nameseq = nameseq;
673 }
674
675 inline
676 posixx::linux::tipc::sockaddr::type_t posixx::linux::tipc::sockaddr::type()
677                 const throw ()
678 {
679         return static_cast< type_t >(addrtype);
680 }
681
682 inline
683 socklen_t posixx::linux::tipc::sockaddr::length() const throw ()
684 {
685         return sizeof(sockaddr_tipc);
686 }
687
688 inline
689 bool posixx::linux::tipc::sockaddr::operator == (const sockaddr& other) const
690                 throw ()
691 {
692         if (family != other.family)
693                 return false;
694         if (addrtype != other.addrtype)
695                 return false;
696         if (scope != other.scope)
697                 return false;
698         if (addrtype == ID)
699                 return port_id() == other.port_id();
700         if (addrtype == NAME)
701                 return name_domain() == other.name_domain()
702                                 && port_name() == other.port_name();
703         if (addrtype == NAMESEQ)
704                 return name_seq() == other.name_seq();
705         return memcmp(this, &other, sizeof(*this)) == 0;
706 }
707
708 inline
709 posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id() throw ()
710 {
711         return *reinterpret_cast<portid*>(&addr.id);
712 }
713
714 inline
715 const posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id()
716                 const throw ()
717 {
718         return *reinterpret_cast<const portid*>(&addr.id);
719 }
720
721 inline
722 posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name() throw ()
723 {
724         return *reinterpret_cast<name*>(&addr.name.name);
725 }
726
727 inline
728 const posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name()
729                 const throw ()
730 {
731         return *reinterpret_cast<const name*>(&addr.name.name);
732 }
733
734 inline
735 posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
736                 throw ()
737 {
738         return *reinterpret_cast<tipc::addr*>(&addr.name.domain);
739 }
740
741 inline
742 const posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
743                 const throw ()
744 {
745         return *reinterpret_cast<const tipc::addr*>(&addr.name.domain);
746 }
747
748 inline
749 posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
750                 throw ()
751 {
752         return *reinterpret_cast<nameseq*>(&addr.nameseq);
753 }
754
755 inline
756 const posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
757                 const throw ()
758 {
759         return *reinterpret_cast<const nameseq*>(&addr.nameseq);
760 }
761
762 #endif // POSIXX_LINUX_TIPC_HPP_