version 0.0.4
[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         db->Execute("CREATE TABLE IF NOT EXISTS tblBoard(\\r
130                                 BoardID                         INTEGER PRIMARY KEY,\\r
131                                 BoardName                       TEXT UNIQUE,\\r
132                                 BoardDescription        TEXT,\\r
133                                 DateAdded                       DATETIME\\r
134                                 );");\r
135 \r
136         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('fms','Freenet Message System','2007-12-01');");\r
137         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('freenet','Discussion about Freenet','2007-12-01');");\r
138         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('public','Public discussion','2007-12-01');");\r
139         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('test','Test board','2007-12-01');");\r
140 \r
141         db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\\r
142                                 MessageID                       INTEGER PRIMARY KEY,\\r
143                                 MessageDate                     DATE,\\r
144                                 MessageTime                     TIME,\\r
145                                 Subject                         TEXT,\\r
146                                 MessageUUID                     TEXT UNIQUE,\\r
147                                 ReplyBoardID            INTEGER,\\r
148                                 Body                            TEXT\\r
149                                 );");\r
150 \r
151         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageReplyTo(\\r
152                                 MessageID                       INTEGER,\\r
153                                 ReplyToMessageID        INTEGER,\\r
154                                 Order                           INTEGER\\r
155                                 );");\r
156         \r
157         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageBoard(\\r
158                                 MessageID                       INTEGER,\\r
159                                 BoardID                         INTEGER\\r
160                                 );");\r
161 \r
162         // low / high / message count for each board\r
163         db->Execute("CREATE VIEW IF NOT EXISTS vwBoardStats AS \\r
164                                 SELECT tblBoard.BoardID AS 'BoardID', IFNULL(MIN(MessageID),0) AS 'LowMessageID', IFNULL(MAX(MessageID),0) AS 'HighMessageID', COUNT(MessageID) AS 'MessageCount' \\r
165                                 FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID \\r
166                                 GROUP BY tblBoard.BoardID;");\r
167 \r
168         // calculates peer trust\r
169         db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \\r
170                                 SELECT TargetIdentityID, \\r
171                                 ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \\r
172                                 ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \\r
173                                 FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \\r
174                                 WHERE LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \\r
175                                 GROUP BY TargetIdentityID;");\r
176 \r
177         // update PeerTrustLevel when deleting a record from tblPeerTrust\r
178         db->Execute("CREATE TRIGGER trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
179                                 FOR EACH ROW \\r
180                                 BEGIN \\r
181                                         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
182                                 END;");\r
183 \r
184         // update PeerTrustLevel when inserting a record into tblPeerTrust\r
185         db->Execute("CREATE TRIGGER trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \\r
186                                 FOR EACH ROW \\r
187                                 BEGIN \\r
188                                         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
189                                 END;");\r
190 \r
191         // update PeerTrustLevel when updating a record in tblPeerTrust\r
192         db->Execute("CREATE TRIGGER trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \\r
193                                 FOR EACH ROW \\r
194                                 BEGIN \\r
195                                         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
196                                         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
197                                 END;");\r
198 \r
199         // 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
200         db->Execute("CREATE TRIGGER trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \\r
201                                 FOR EACH ROW \\r
202                                 BEGIN \\r
203                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\\r
204                                 END;");\r
205 \r
206 }\r
207 \r
208 void SetupDefaultOptions()\r
209 {\r
210         // 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
211 \r
212         std::ostringstream tempstr;     // must set tempstr to "" between db inserts\r
213         SQLite3DB::DB *db=SQLite3DB::DB::instance();\r
214         SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");\r
215 \r
216         // LogLevel\r
217         tempstr.str("");\r
218         tempstr << LogFile::LOGLEVEL_DEBUG;\r
219         st.Bind(0,"LogLevel");\r
220         st.Bind(1,tempstr.str());\r
221         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
222         st.Step();\r
223         st.Reset();\r
224 \r
225         // StartFreenetUpdater\r
226         st.Bind(0,"StartFreenetUpdater");\r
227         st.Bind(1,"true");\r
228         st.Bind(2,"Start Freenet Updater thread.");\r
229         st.Step();\r
230         st.Reset();\r
231 \r
232         // FCPHost\r
233         st.Bind(0,"FCPHost");\r
234         st.Bind(1,"localhost");\r
235         st.Bind(2,"Host name or address of Freenet node.");\r
236         st.Step();\r
237         st.Reset();\r
238 \r
239         // FCPPort\r
240         st.Bind(0,"FCPPort");\r
241         st.Bind(1,"9481");\r
242         st.Bind(2,"The port that Freenet is listening for FCP connections on.");\r
243         st.Step();\r
244         st.Reset();\r
245 \r
246         st.Bind(0,"MessageBase");\r
247         st.Bind(1,"fms");\r
248         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
249         st.Step();\r
250         st.Reset();\r
251 \r
252         st.Bind(0,"MaxIdentityRequests");\r
253         st.Bind(1,"5");\r
254         st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");\r
255         st.Step();\r
256         st.Reset();\r
257 \r
258         st.Bind(0,"MaxIdentityIntroductionRequests");\r
259         st.Bind(1,"5");\r
260         st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files.  Each identity may have multiple requests pending.");\r
261         st.Step();\r
262         st.Reset();\r
263 \r
264         st.Bind(0,"MaxIntroductionPuzzleRequests");\r
265         st.Bind(1,"5");\r
266         st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");\r
267         st.Step();\r
268         st.Reset();\r
269 \r
270         st.Bind(0,"MaxTrustListRequests");\r
271         st.Bind(1,"5");\r
272         st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");\r
273         st.Step();\r
274         st.Reset();\r
275 \r
276         st.Bind(0,"MinLocalTrustListTrust");\r
277         st.Bind(1,"50");\r
278         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
279         st.Step();\r
280         st.Reset();\r
281 \r
282 }\r
283 \r
284 void SetupLogFile()\r
285 {\r
286         DateTime date;\r
287         std::string configval;\r
288         int loglevel;\r
289 \r
290         date.SetToGMTime();\r
291 \r
292         LogFile::instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");\r
293         LogFile::instance()->OpenFile();\r
294         LogFile::instance()->SetWriteNewLine(true);\r
295         LogFile::instance()->SetWriteDate(true);\r
296         LogFile::instance()->SetWriteLogLevel(true);\r
297 \r
298         if(Option::instance()->Get("LogLevel",configval)==false)\r
299         {\r
300                 configval="4";\r
301                 Option::instance()->Set("LogLevel",configval);\r
302         }\r
303         if(StringFunctions::Convert(configval,loglevel)==false)\r
304         {\r
305                 loglevel=LogFile::LOGLEVEL_DEBUG;\r
306                 Option::instance()->Set("LogLevel",loglevel);\r
307         }\r
308         LogFile::instance()->SetLogLevel((LogFile::LogLevel)loglevel);\r
309 }\r
310 \r
311 void SetupNetwork()\r
312 {\r
313 #ifdef _WIN32\r
314         WSAData wsadata;\r
315         WSAStartup(MAKEWORD(2,2),&wsadata);\r
316 #endif\r
317 }\r
318 \r
319 void ShutdownNetwork()\r
320 {\r
321 #ifdef _WIN32\r
322         WSACleanup();\r
323 #endif\r
324 }\r
325 \r
326 void ShutdownThreads(std::vector<ZThread::Thread *> &threads)\r
327 {\r
328         std::vector<ZThread::Thread *>::iterator i;\r
329         for(i=threads.begin(); i!=threads.end(); i++)\r
330         {\r
331                 if((*i)->wait(1)==false)\r
332                 {\r
333                         try\r
334                         {\r
335                                 (*i)->interrupt();\r
336                         }\r
337                         catch(...)\r
338                         {\r
339                         }\r
340                 }\r
341         }\r
342 \r
343         for(i=threads.begin(); i!=threads.end(); i++)\r
344         {\r
345                 (*i)->wait();\r
346                 delete (*i);\r
347         }\r
348 \r
349         threads.clear();\r
350 \r
351 }\r
352 \r
353 void StartThreads(std::vector<ZThread::Thread *> &threads)\r
354 {\r
355         std::string startfreenet;\r
356         std::string startnntp;\r
357 \r
358         if(Option::instance()->Get("StartFreenetUpdater",startfreenet)==false)\r
359         {\r
360                 startfreenet="true";\r
361                 Option::instance()->Set("StartFreenetUpdater","true");\r
362         }\r
363 \r
364         if(startfreenet=="true")\r
365         {\r
366                 ZThread::Thread *t=new ZThread::Thread(new FreenetMasterThread());\r
367                 threads.push_back(t);\r
368         }\r
369 \r
370 }\r