version 0.0.2
[fms.git] / src / identitytestglobal.cpp
1 #include "../include/identitytestglobal.h"\r
2 #include "../include/datetime.h"\r
3 #include "../include/logfile.h"\r
4 #include "../include/option.h"\r
5 #include "../include/stringfunctions.h"\r
6 #include "../include/db/sqlite3db.h"\r
7 #include "../include/freenet/freenetmasterthread.h"\r
8 \r
9 #ifdef _WIN32\r
10         #include <winsock2.h>\r
11 #endif\r
12 \r
13 #ifdef XMEM\r
14         #include <xmem.h>\r
15 #endif\r
16 \r
17 void SetupDB()\r
18 {\r
19 \r
20         SQLite3DB::DB *db=SQLite3DB::DB::instance();\r
21 \r
22         db->Open("fms.db3");\r
23         db->SetBusyTimeout(10000);              // set timeout to 10 seconds\r
24         db->Execute("VACUUM;");\r
25 \r
26         db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
27                                 Option                          TEXT UNIQUE,\\r
28                                 OptionValue                     TEXT NOT NULL,\\r
29                                 OptionDescription       TEXT\\r
30                                 );");\r
31 \r
32         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
33                                 LocalIdentityID                 INTEGER PRIMARY KEY,\\r
34                                 Name                                    TEXT,\\r
35                                 PublicKey                               TEXT,\\r
36                                 PrivateKey                              TEXT,\\r
37                                 SingleUse                               BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
38                                 PublishTrustList                BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
39                                 PublishBoardList                BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
40                                 InsertingIdentity               BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\\r
41                                 LastInsertedIdentity    DATETIME,\\r
42                                 InsertingPuzzle                 BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\\r
43                                 LastInsertedPuzzle              DATETIME,\\r
44                                 InsertingTrustList              BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\\r
45                                 LastInsertedTrustList   DATETIME,\\r
46                                 InsertingBoardList              BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\\r
47                                 LastInsertedBoardList   DATETIME\\r
48                                 );");\r
49 \r
50         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\\r
51                                 LocalIdentityID         INTEGER,\\r
52                                 Day                                     DATE,\\r
53                                 InsertIndex                     INTEGER\\r
54                                 );");\r
55 \r
56         db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListInserts(\\r
57                                 LocalIdentityID         INTEGER,\\r
58                                 Day                                     DATE,\\r
59                                 InsertIndex                     INTEGER\\r
60                                 );");\r
61 \r
62         db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListRequests(\\r
63                                 IdentityID                      INTEGER,\\r
64                                 Day                                     DATE,\\r
65                                 RequestIndex            INTEGER,\\r
66                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
67                                 );");\r
68 \r
69         db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleInserts(\\r
70                                 UUID                            TEXT UNIQUE,\\r
71                                 LocalIdentityID         INTEGER,\\r
72                                 Day                                     DATE,\\r
73                                 InsertIndex                     INTEGER,\\r
74                                 Type                            TEXT,\\r
75                                 MimeType                        TEXT,\\r
76                                 PuzzleData                      TEXT,\\r
77                                 PuzzleSolution          TEXT,\\r
78                                 FoundSolution           BOOL CHECK(FoundSolution IN('true','false')) DEFAULT 'false'\\r
79                                 );");\r
80 \r
81         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
82                                 IdentityID                      INTEGER PRIMARY KEY,\\r
83                                 PublicKey                       TEXT,\\r
84                                 Name                            TEXT,\\r
85                                 SingleUse                       BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
86                                 PublishTrustList        BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
87                                 PublishBoardList        BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
88                                 DateAdded                       DATETIME,\\r
89                                 LastSeen                        DATETIME,\\r
90                                 LocalMessageTrust       INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\\r
91                                 PeerMessageTrust        INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\\r
92                                 LocalTrustListTrust     INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT 50,\\r
93                                 PeerTrustListTrust      INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT 50\\r
94                                 );");\r
95 \r
96         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\\r
97                                 IdentityID                      INTEGER,\\r
98                                 Day                                     DATE,\\r
99                                 RequestIndex            INTEGER,\\r
100                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
101                                 );");\r
102 \r
103         db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleRequests(\\r
104                                 IdentityID                      INTEGER,\\r
105                                 Day                                     DATE,\\r
106                                 RequestIndex            INTEGER,\\r
107                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false',\\r
108                                 UUID                            TEXT UNIQUE,\\r
109                                 Type                            TEXT,\\r
110                                 MimeType                        TEXT,\\r
111                                 PuzzleData                      TEXT\\r
112                                 );");\r
113 \r
114         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityIntroductionInserts(\\r
115                                 LocalIdentityID         INTEGER,\\r
116                                 Day                                     DATE,\\r
117                                 UUID                            TEXT UNIQUE,\\r
118                                 Solution                        TEXT,\\r
119                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
120                                 );");\r
121 \r
122         db->Execute("CREATE TABLE IF NOT EXISTS tblPeerTrust(\\r
123                                 IdentityID                      INTEGER,\\r
124                                 TargetIdentityID        INTEGER,\\r
125                                 MessageTrust            INTEGER CHECK(MessageTrust BETWEEN 0 AND 100),\\r
126                                 TrustListTrust          INTEGER CHECK(TrustListTrust BETWEEN 0 AND 100)\\r
127                                 );");\r
128 \r
129         // calculates peer trust\r
130         db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \\r
131                                 SELECT TargetIdentityID, \\r
132                                 ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \\r
133                                 ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \\r
134                                 FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \\r
135                                 WHERE LocalTrustListTrust>(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \\r
136                                 GROUP BY TargetIdentityID;");\r
137 \r
138         // update PeerTrustLevel when deleting a record from tblPeerTrust\r
139         db->Execute("CREATE TRIGGER trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
140                                 FOR EACH ROW \\r
141                                 BEGIN \\r
142                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
143                                 END;");\r
144 \r
145         // update PeerTrustLevel when inserting a record into tblPeerTrust\r
146         db->Execute("CREATE TRIGGER trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \\r
147                                 FOR EACH ROW \\r
148                                 BEGIN \\r
149                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID) WHERE IdentityID=new.TargetIdentityID;\\r
150                                 END;");\r
151 \r
152         // update PeerTrustLevel when updating a record in tblPeerTrust\r
153         db->Execute("CREATE TRIGGER trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \\r
154                                 FOR EACH ROW \\r
155                                 BEGIN \\r
156                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
157                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID) WHERE IdentityID=new.TargetIdentityID;\\r
158                                 END;");\r
159 \r
160         // recalculate all Peer TrustLevels when updating Local TrustLevels on tblIdentity - doesn't really need to be all, but rather all identities the updated identity has a trust level for.  It's easier to update everyone for now.\r
161         db->Execute("CREATE TRIGGER trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \\r
162                                 FOR EACH ROW \\r
163                                 BEGIN \\r
164                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\\r
165                                 END;");\r
166 \r
167 }\r
168 \r
169 void SetupDefaultOptions()\r
170 {\r
171         // OptionValue should always be inserted as a string, even if the option really isn't a string - just to keep the field data type consistent\r
172 \r
173         std::ostringstream tempstr;     // must set tempstr to "" between db inserts\r
174         SQLite3DB::DB *db=SQLite3DB::DB::instance();\r
175         SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");\r
176 \r
177         // LogLevel\r
178         tempstr.str("");\r
179         tempstr << LogFile::LOGLEVEL_DEBUG;\r
180         st.Bind(0,"LogLevel");\r
181         st.Bind(1,tempstr.str());\r
182         st.Bind(2,"The maximum logging level that will be written to file.  0=Fatal Errors, 1=Errors, 2=Warnings, 3=Informational Messages, 4=Debug Messages.  Higher levels will include all messages from the previous levels.");\r
183         st.Step();\r
184         st.Reset();\r
185 \r
186         // StartFreenetUpdater\r
187         st.Bind(0,"StartFreenetUpdater");\r
188         st.Bind(1,"true");\r
189         st.Bind(2,"Start Freenet Updater.");\r
190         st.Step();\r
191         st.Reset();\r
192 \r
193         // FCPHost\r
194         st.Bind(0,"FCPHost");\r
195         st.Bind(1,"localhost");\r
196         st.Bind(2,"Host name or address of Freenet node.");\r
197         st.Step();\r
198         st.Reset();\r
199 \r
200         // FCPPort\r
201         st.Bind(0,"FCPPort");\r
202         st.Bind(1,"9481");\r
203         st.Bind(2,"The port that Freenet is listening for FCP connections on.");\r
204         st.Step();\r
205         st.Reset();\r
206 \r
207         st.Bind(0,"MessageBase");\r
208         st.Bind(1,"fms");\r
209         st.Bind(2,"A unique string shared by all clients who want to communicate with each other.  This should not be changed unless you want to create your own separate communications network.");\r
210         st.Step();\r
211         st.Reset();\r
212 \r
213         st.Bind(0,"MaxIdentityRequests");\r
214         st.Bind(1,"5");\r
215         st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");\r
216         st.Step();\r
217         st.Reset();\r
218 \r
219         st.Bind(0,"MaxIdentityIntroductionRequests");\r
220         st.Bind(1,"5");\r
221         st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files.  Each identity may have multiple requests pending.");\r
222         st.Step();\r
223         st.Reset();\r
224 \r
225         st.Bind(0,"MaxIntroductionPuzzleRequests");\r
226         st.Bind(1,"5");\r
227         st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");\r
228         st.Step();\r
229         st.Reset();\r
230 \r
231         st.Bind(0,"MaxTrustListRequests");\r
232         st.Bind(1,"5");\r
233         st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");\r
234         st.Step();\r
235         st.Reset();\r
236 \r
237         st.Bind(0,"MinLocalTrustListTrust");\r
238         st.Bind(1,"50");\r
239         st.Bind(2,"Specifies a local trust list trust level that a peer must have before its trust list will be included in the weighted average.  Any peers below this number will be excluded from the results.");\r
240         st.Step();\r
241         st.Reset();\r
242 \r
243 }\r
244 \r
245 void SetupLogFile()\r
246 {\r
247         DateTime date;\r
248         std::string configval;\r
249         int loglevel;\r
250 \r
251         date.SetToGMTime();\r
252 \r
253         LogFile::instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");\r
254         LogFile::instance()->OpenFile();\r
255         LogFile::instance()->SetWriteNewLine(true);\r
256         LogFile::instance()->SetWriteDate(true);\r
257         LogFile::instance()->SetWriteLogLevel(true);\r
258 \r
259         if(Option::instance()->Get("LogLevel",configval)==false)\r
260         {\r
261                 configval="4";\r
262                 Option::instance()->Set("LogLevel",configval);\r
263         }\r
264         if(StringFunctions::Convert(configval,loglevel)==false)\r
265         {\r
266                 loglevel=LogFile::LOGLEVEL_DEBUG;\r
267                 Option::instance()->Set("LogLevel",loglevel);\r
268         }\r
269         LogFile::instance()->SetLogLevel((LogFile::LogLevel)loglevel);\r
270 }\r
271 \r
272 void SetupNetwork()\r
273 {\r
274 #ifdef _WIN32\r
275         WSAData wsadata;\r
276         WSAStartup(MAKEWORD(2,2),&wsadata);\r
277 #endif\r
278 }\r
279 \r
280 void ShutdownNetwork()\r
281 {\r
282 #ifdef _WIN32\r
283         WSACleanup();\r
284 #endif\r
285 }\r
286 \r
287 void ShutdownThreads(std::vector<ZThread::Thread *> &threads)\r
288 {\r
289         std::vector<ZThread::Thread *>::iterator i;\r
290         for(i=threads.begin(); i!=threads.end(); i++)\r
291         {\r
292                 if((*i)->wait(1)==false)\r
293                 {\r
294                         try\r
295                         {\r
296                                 (*i)->interrupt();\r
297                         }\r
298                         catch(...)\r
299                         {\r
300                         }\r
301                 }\r
302         }\r
303 \r
304         for(i=threads.begin(); i!=threads.end(); i++)\r
305         {\r
306                 (*i)->wait();\r
307                 delete (*i);\r
308         }\r
309 \r
310         threads.clear();\r
311 \r
312 }\r
313 \r
314 void StartThreads(std::vector<ZThread::Thread *> &threads)\r
315 {\r
316         std::string startfreenet;\r
317         std::string startnntp;\r
318 \r
319         if(Option::instance()->Get("StartFreenetUpdater",startfreenet)==false)\r
320         {\r
321                 startfreenet="true";\r
322                 Option::instance()->Set("StartFreenetUpdater","true");\r
323         }\r
324 \r
325         if(startfreenet=="true")\r
326         {\r
327                 ZThread::Thread *t=new ZThread::Thread(new FreenetMasterThread());\r
328                 threads.push_back(t);\r
329         }\r
330 \r
331 }\r