Merge branch 'master' of feistymeow.org:feisty_meow
[feisty_meow.git] / octopi / library / sockets / machine_uid.h
1 #ifndef MACHINE_UID_CLASS
2 #define MACHINE_UID_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : machine_uid                                                       *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *  Purpose:                                                                   *
10 *                                                                             *
11 *    This object identifies a machine uniquely within a particular network    *
12 *  configuration.  It is not world-unique, since some location names are not  *
13 *  either.  For example, a TCP/IP address like 10.2.13.9 might be used many   *
14 *  times around the world, since it is reserved for private networks.  But    *
15 *  within one valid network configuration, there should not be more than one  *
16 *  of these addresses.  If there are, then be aware that multiple machines    *
17 *  might answer to a particular address and invalidate some assumptions of    *
18 *  uniqueness.                                                                *
19 *    The machine_uid is most useful when a program wishes to ensure that it   *
20 *  treats a machine only once when it is performing some form of processing   *
21 *  for that address.  For example, the id could be contained within a 'set'   *
22 *  to ensure that a message is only sent once to each machine of interest.    *
23 *                                                                             *
24 *******************************************************************************
25 * Copyright (c) 2000-$now By Author.  This program is free software; you can  *
26 * redistribute it and/or modify it under the terms of the GNU General Public  *
27 * License as published by the Free Software Foundation; either version 2 of   *
28 * the License or (at your option) any later version.  This is online at:      *
29 *     http://www.fsf.org/copyleft/gpl.html                                    *
30 * Please send any updates to: fred@gruntose.com                               *
31 \*****************************************************************************/
32
33 #include <basis/astring.h>
34 #include <basis/byte_array.h>
35 #include <basis/contracts.h>
36
37 namespace sockets {
38
39 // forward.
40 class internal_machine_uid_array;
41
42 class machine_uid : public virtual basis::packable
43 {
44 public:
45   enum known_location_types {
46     INVALID_LOCATION,            // this id has not been initialized.
47     TCPIP_LOCATION,              // a location on the internet.
48     IPX_LOCATION,                // a host on an IPX/SPX network.
49     NETBIOS_LOCATION             // a machine reachable by SMB protocol.
50   };
51   static const basis::astring &type_name(known_location_types type);
52     // returns the text form for the "type" specified.
53
54   machine_uid();  // constructs an invalid id.
55
56   machine_uid(known_location_types type, const basis::byte_array &address);
57     // sets up an id for the "type" specified given the serialized "address".
58     // the format used here is that bytes follow in the natural listing order
59     // for the address "type".
60
61   machine_uid(const machine_uid &to_copy);  // copy constructor.
62
63   virtual ~machine_uid();
64
65   known_location_types type() const;
66     // returns the type currently held.
67
68   bool valid() const { return type() != INVALID_LOCATION; }
69     // returns true if this id seems possibly valid.  an id for which this
70     // returns true could still have protocol specific issues that make it
71     // invalid, but as far as this class can tell, it looks okay.
72
73   machine_uid &operator =(const machine_uid &to_copy);
74
75   void reset(known_location_types type, const basis::byte_array &address);
76     // reconstructs the machine_uid with new parameters.
77
78   basis::astring text_form() const;
79     // returns a string that describes the address held here.
80
81   basis::astring compact_form() const;
82     // returns a non-readable string form of the id that is more efficient.
83   static machine_uid expand(const basis::astring &compacted);
84     // gets the original machine_uid out of the "compacted" form.
85
86   basis::byte_array native() const;
87     // returns the identifier for the machine in the native format.  for
88     // internet1, this is 4 bytes of IP address.
89
90   // equality means: same protocol type, same key length, and same contents.
91   bool operator == (const machine_uid &to_compare) const;
92
93   // meets the requirements of packable.
94   virtual int packed_size() const;
95   virtual void pack(basis::byte_array &packed_form) const;
96   virtual bool unpack(basis::byte_array &packed_form);
97
98   const basis::byte_array &raw() const;
99     // returns the raw internal representation for the machine_uid.
100
101 private:
102   basis::byte_array *_contents;
103 };
104
105 //////////////
106
107 class internet_machine_uid : public machine_uid
108 {
109 public:
110   internet_machine_uid(const basis::astring &hostname, const basis::byte_array &ip_address);
111     // constructs a machine uid that almost always uniquely identifies a
112     // machine on the internet.  if all ip addresses in a system are unique,
113     // then IMU is always unique.  however, if all ip addresses in a system
114     // are not unique, then the IMU can discriminate the hostname as long as
115     // no two hostnames resolve to the same checksum.
116 };
117
118 //////////////
119
120 // this object contains a list of unique machine identifiers.  this is
121 // intentionally just an array (and not a set) because some usages of the
122 // list of machine_uids need a notion of ordering (such as for a list of
123 // machines that have touched a packet).
124
125 class machine_uid_array : public virtual basis::root_object
126 {
127 public:
128   machine_uid_array();
129   machine_uid_array(const machine_uid_array &to_copy);
130   ~machine_uid_array();
131   DEFINE_CLASS_NAME("machine_uid_array");
132
133   static const machine_uid_array &blank_array();
134
135   machine_uid_array &operator =(const machine_uid_array &to_copy);
136
137   bool operator += (const machine_uid &to_add);
138
139   basis::astring text_form() const;
140
141   int elements() const;
142
143   void reset();
144
145   machine_uid &operator [] (int index);
146   const machine_uid &operator [] (int index) const;
147
148   bool member(const machine_uid &to_test) const;
149     // returns true if the id "to_test" is a member of the list of machine
150     // ids held here.  if the machine_uid's are of different sizes, then a
151     // prefix compare is used.  this allows an id without the host
152     // discriminator portion to match the full version.
153
154 private:
155   internal_machine_uid_array *_uids;  // the underlying machine_uid list.
156 };
157
158 } //namespace.
159
160 #endif
161