Merge branch 'master' of feistymeow.org:feisty_meow
[feisty_meow.git] / octopi / library / tentacles / simple_entity_registry.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : simple_entity_registry                                            *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 2002-$now By Author.  This program is free software; you can  *
8 * redistribute it and/or modify it under the terms of the GNU General Public  *
9 * License as published by the Free Software Foundation; either version 2 of   *
10 * the License or (at your option) any later version.  This is online at:      *
11 *     http://www.fsf.org/copyleft/gpl.html                                    *
12 * Please send any updates to: fred@gruntose.com                               *
13 \*****************************************************************************/
14
15 #include "simple_entity_registry.h"
16
17 #include <basis/mutex.h>
18 #include <structures/string_hash.h>
19 #include <octopus/entity_defs.h>
20
21 using namespace basis;
22 using namespace octopi;
23 using namespace structures;
24 using namespace timely;
25
26 namespace octopi {
27
28 #undef GRAB_LOCK
29 #define GRAB_LOCK \
30   auto_synchronizer l(*_secure_lock)
31
32 #undef LOG
33 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s);
34
35 const int ENTITY_HASH_BITS = 8;
36   // the hash table for entities will be 2^N wide.
37
38 // this record is stored for each verified entity.  if such a record exists,
39 // then the entity has passed through whatever security system is installed
40 // in the octopus.
41
42 //////////////
43
44 class recognized_entity
45 {
46 public:
47   octopus_entity _entity;    // the identifier for this entity.
48   time_stamp _last_active;   // when was this entity last active?
49   byte_array _verification;  // verification information sent by entity.
50 };
51
52 //////////////
53
54 class recognized_entity_list : public string_hash<recognized_entity>
55 {
56 public:
57   recognized_entity_list() : string_hash<recognized_entity>(ENTITY_HASH_BITS) {}
58 };
59
60 //////////////
61
62 simple_entity_registry::simple_entity_registry()
63 : _secure_lock(new mutex),
64   _entities(new recognized_entity_list)
65 {
66 }
67
68 simple_entity_registry::~simple_entity_registry()
69 {
70   WHACK(_entities);
71   WHACK(_secure_lock);
72 }
73
74 bool simple_entity_registry::authorized(const octopus_entity &entity)
75 {
76   GRAB_LOCK;
77   recognized_entity *found = _entities->find(entity.mangled_form());
78   return !!found;
79 }
80
81 bool simple_entity_registry::refresh_entity(const octopus_entity &entity)
82 {
83   GRAB_LOCK;
84   recognized_entity *found = _entities->find(entity.mangled_form());
85   if (!found) return false;
86   // we found their record so update that time stamp.
87   found->_last_active = time_stamp();
88   return true;
89 }
90
91 bool simple_entity_registry::add_entity(const octopus_entity &entity,
92     const byte_array &verification)
93 {
94   GRAB_LOCK;
95   recognized_entity *found = _entities->find(entity.mangled_form());
96   if (found) {
97     // already had a record for this guy so update the time stamp.
98     found->_last_active = time_stamp();
99     // if there's a verification token, make sure we keep their most recent
100     // version of it.
101     if (verification.length())
102       found->_verification = verification;
103   } else {
104     // this is a new entity, so add a new entity record for it.
105     recognized_entity *new_one = new recognized_entity;
106     new_one->_entity = entity;
107     new_one->_verification = verification;
108     _entities->add(entity.mangled_form(), new_one);
109   }
110   return true;
111 }
112
113 bool simple_entity_registry::zap_entity(const octopus_entity &entity)
114 {
115   GRAB_LOCK;
116   return _entities->zap(entity.mangled_form());
117 }
118
119 bool simple_entity_registry::locate_entity(const octopus_entity &entity,
120     time_stamp &last_active, byte_array &verification)
121 {
122   GRAB_LOCK;
123   recognized_entity *found = _entities->find(entity.mangled_form());
124   if (!found) return false;
125   last_active = found->_last_active;
126   verification = found->_verification;
127   return true;
128 }
129
130 bool text_form_applier(const astring &formal(key), recognized_entity &info,
131     void *datalink)
132 {
133   astring *accum = (astring *)datalink;
134   *accum += astring("ent=") + info._entity.mangled_form() + ", active="
135       + info._last_active.text_form()
136       + a_sprintf(", %d veribytes", info._verification.length());
137   return true;
138 }
139
140 astring simple_entity_registry::text_form()
141 {
142   astring to_return;
143   GRAB_LOCK;
144   _entities->apply(text_form_applier, &to_return);
145   return to_return;
146 }
147
148 } //namespace.
149