8962d5e9a7ee886ca29eb901446d48835f4fdbeb
[fms.git] / src / freenet / trustlistinserter.cpp
1 #include "../../include/freenet/trustlistinserter.h"\r
2 #include "../../include/option.h"\r
3 #include "../../include/freenet/trustlistxml.h"\r
4 #include "../../include/stringfunctions.h"\r
5 \r
6 #ifdef XMEM\r
7         #include <xmem.h>\r
8 #endif\r
9 \r
10 TrustListInserter::TrustListInserter()\r
11 {\r
12         Initialize();\r
13 }\r
14 \r
15 TrustListInserter::TrustListInserter(FCPv2 *fcp):IFCPConnected(fcp)\r
16 {\r
17         Initialize();\r
18 }\r
19 \r
20 void TrustListInserter::CheckForNeededInsert()\r
21 {\r
22         DateTime date;\r
23         date.SetToGMTime();\r
24         int currentday=date.GetDay();\r
25         date.Add(0,0,-6);\r
26         // insert trust lists every 6 hours - if 6 hours ago was different day then set to midnight of current day to insert list today ASAP\r
27         if(currentday!=date.GetDay())\r
28         {\r
29                 date.Set(date.GetYear(),date.GetMonth(),currentday);\r
30         }\r
31         SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID, PrivateKey FROM tblLocalIdentity WHERE PrivateKey IS NOT NULL AND PrivateKey <> '' AND PublishTrustList='true' AND InsertingTrustList='false' AND (LastInsertedTrustList<='"+date.Format("%Y-%m-%d %H:%M:%S")+"' OR LastInsertedTrustList IS NULL);");\r
32 \r
33         if(rs.Empty()==false)\r
34         {\r
35                 StartInsert(rs.GetInt(0),rs.GetField(1));\r
36         }\r
37 }\r
38 \r
39 void TrustListInserter::FCPConnected()\r
40 {\r
41         m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false';");\r
42 }\r
43 \r
44 void TrustListInserter::FCPDisconnected()\r
45 {\r
46 \r
47 }\r
48 \r
49 const bool TrustListInserter::HandleMessage(FCPMessage &message)\r
50 {\r
51 \r
52         if(message["Identifier"].find("TrustListInserter")==0)\r
53         {\r
54                 \r
55                 DateTime now;\r
56                 std::vector<std::string> idparts;\r
57 \r
58                 now.SetToGMTime();\r
59                 StringFunctions::Split(message["Identifier"],"|",idparts);\r
60 \r
61                 // no action for URIGenerated\r
62                 if(message.GetName()=="URIGenerated")\r
63                 {\r
64                         return true;\r
65                 }\r
66 \r
67                 // no action for IdentifierCollision\r
68                 if(message.GetName()=="IdentifierCollision")\r
69                 {\r
70                         return true;\r
71                 }\r
72 \r
73                 if(message.GetName()=="PutSuccessful")\r
74                 {\r
75                         m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false', LastInsertedTrustList='"+now.Format("%Y-%m-%d %H:%M:%S")+"' WHERE LocalIdentityID="+idparts[1]+";");\r
76                         m_db->Execute("INSERT INTO tblTrustListInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
77                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"TrustListInserter::HandleMessage inserted TrustList xml");\r
78                         return true;\r
79                 }\r
80 \r
81                 if(message.GetName()=="PutFailed")\r
82                 {\r
83                         m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false' WHERE LocalIdentityID="+idparts[1]+";");\r
84                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"TrustListInserter::HandleMessage failure inserting TrustList xml.  Code="+message["Code"]+" Description="+message["CodeDescription"]);\r
85                         \r
86                         // if code 9 (collision), then insert index into inserted table\r
87                         if(message["Code"]=="9")\r
88                         {\r
89                                 m_db->Execute("INSERT INTO tblTrustListInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
90                         }\r
91                         \r
92                         return true;\r
93                 }\r
94 \r
95         }\r
96 \r
97         return false;\r
98 }\r
99 \r
100 void TrustListInserter::Initialize()\r
101 {\r
102         Option::Instance()->Get("MessageBase",m_messagebase);\r
103         m_lastchecked.SetToGMTime();\r
104 }\r
105 \r
106 void TrustListInserter::Process()\r
107 {\r
108         DateTime now;\r
109         now.SetToGMTime();\r
110 \r
111         // check every minute\r
112         if(m_lastchecked<=(now-(1.0/1440.0)))\r
113         {\r
114                 CheckForNeededInsert();\r
115                 m_lastchecked=now;\r
116         }\r
117 }\r
118 \r
119 void TrustListInserter::RegisterWithThread(FreenetMasterThread *thread)\r
120 {\r
121         thread->RegisterFCPConnected(this);\r
122         thread->RegisterFCPMessageHandler(this);\r
123         thread->RegisterPeriodicProcessor(this);\r
124 }\r
125 \r
126 void TrustListInserter::StartInsert(const long localidentityid, const std::string &privatekey)\r
127 {\r
128         FCPMessage message;\r
129         TrustListXML xml;\r
130         std::string data;\r
131         std::string datasizestr;\r
132         std::string publickey;\r
133         int messagetrust;\r
134         int trustlisttrust;\r
135         DateTime now,date;\r
136         int index;\r
137         std::string indexstr;\r
138         std::string localidentityidstr;\r
139         std::string messagetrustcomment="";\r
140         std::string trustlisttrustcomment="";\r
141 \r
142         now.SetToGMTime();\r
143         date.SetToGMTime();\r
144 \r
145         // insert all identities not in trust list already\r
146         m_db->Execute("INSERT INTO tblIdentityTrust(LocalIdentityID,IdentityID) SELECT LocalIdentityID,IdentityID FROM tblLocalIdentity,tblIdentity WHERE LocalIdentityID || '_' || IdentityID NOT IN (SELECT LocalIdentityID || '_' || IdentityID FROM tblIdentityTrust);");\r
147 \r
148         // build the xml file - we only want to add identities that we recently saw, otherwise we could be inserting a ton of identities\r
149         date.Add(0,0,0,-20);    // identities seen in last 20 days\r
150         //SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey, LocalMessageTrust, LocalTrustListTrust, MessageTrustComment, TrustListTrustComment FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey<>'' AND LastSeen>=?;");\r
151         // we want to order by public key so we can't do identity correllation based on the sequence of identities in the list.\r
152         SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey, tblIdentityTrust.LocalMessageTrust, tblIdentityTrust.LocalTrustListTrust, tblIdentityTrust.MessageTrustComment, tblIdentityTrust.TrustListTrustComment FROM tblIdentity INNER JOIN tblIdentityTrust ON tblIdentity.IdentityID=tblIdentityTrust.IdentityID WHERE PublicKey IS NOT NULL AND PublicKey<>'' AND LastSeen>=? AND tblIdentityTrust.LocalIdentityID=? ORDER BY PublicKey;");\r
153         st.Bind(0,date.Format("%Y-%m-%d"));\r
154         st.Bind(1,localidentityid);\r
155         st.Step();\r
156         while(st.RowReturned())\r
157         {\r
158                 st.ResultText(0,publickey);\r
159                 if(st.ResultNull(1)==false)\r
160                 {\r
161                         st.ResultInt(1,messagetrust);\r
162                 }\r
163                 else\r
164                 {\r
165                         messagetrust=-1;\r
166                 }\r
167                 if(st.ResultNull(2)==false)\r
168                 {\r
169                         st.ResultInt(2,trustlisttrust);\r
170                 }\r
171                 else\r
172                 {\r
173                         trustlisttrust=-1;\r
174                 }\r
175                 st.ResultText(3,messagetrustcomment);\r
176                 st.ResultText(4,trustlisttrustcomment);\r
177                 xml.AddTrust(publickey,messagetrust,trustlisttrust,messagetrustcomment,trustlisttrustcomment);\r
178                 st.Step();\r
179         }\r
180 \r
181         // get next insert index\r
182         st=m_db->Prepare("SELECT MAX(InsertIndex) FROM tblTrustListInserts WHERE LocalIdentityID=? AND Day=?;");\r
183         st.Bind(0,localidentityid);\r
184         st.Bind(1,now.Format("%Y-%m-%d"));\r
185         st.Step();\r
186 \r
187         index=0;\r
188         if(st.RowReturned() && st.ResultNull(0)==false)\r
189         {\r
190                 st.ResultInt(0,index);\r
191                 index++;\r
192         }\r
193 \r
194         StringFunctions::Convert(localidentityid,localidentityidstr);\r
195         StringFunctions::Convert(index,indexstr);\r
196 \r
197         data=xml.GetXML();\r
198         StringFunctions::Convert(data.size(),datasizestr);\r
199 \r
200         message.SetName("ClientPut");\r
201         message["URI"]=privatekey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|TrustList|"+indexstr+".xml";\r
202         message["Identifier"]="TrustListInserter|"+localidentityidstr+"|"+indexstr+"|"+message["URI"];\r
203         message["UploadFrom"]="direct";\r
204         message["DataLength"]=datasizestr;\r
205         m_fcp->SendMessage(message);\r
206         m_fcp->SendRaw(data.c_str(),data.size());\r
207 \r
208         m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='true' WHERE LocalIdentityID="+localidentityidstr+";");\r
209 \r
210 }\r