version 0.1.9
[fms.git] / src / freenet / freenetmasterthread.cpp
1 #include "../../include/freenet/freenetmasterthread.h"\r
2 #include "../../include/option.h"\r
3 #include "../../include/uuidgenerator.h"\r
4 #include "../../include/stringfunctions.h"\r
5 #include "../../include/freenet/unkeyedidcreator.h"\r
6 #include "../../include/freenet/identityinserter.h"\r
7 #include "../../include/freenet/identityrequester.h"\r
8 #include "../../include/freenet/introductionpuzzleinserter.h"\r
9 #include "../../include/freenet/identityintroductionrequester.h"\r
10 #include "../../include/freenet/introductionpuzzlerequester.h"\r
11 #include "../../include/freenet/identityintroductioninserter.h"\r
12 #include "../../include/freenet/trustlistinserter.h"\r
13 #include "../../include/freenet/trustlistrequester.h"\r
14 #include "../../include/freenet/messagelistrequester.h"\r
15 #include "../../include/freenet/messagerequester.h"\r
16 #include "../../include/freenet/messageinserter.h"\r
17 #include "../../include/freenet/messagelistinserter.h"\r
18 #include "../../include/freenet/periodicdbmaintenance.h"\r
19 \r
20 //#include <zthread/Thread.h>\r
21 #include "../../include/pthreadwrapper/thread.h"\r
22 \r
23 #ifdef XMEM\r
24         #include <xmem.h>\r
25 #endif\r
26 \r
27 FreenetMasterThread::FreenetMasterThread()\r
28 {\r
29         std::string fcpport;\r
30 \r
31         if(Option::Instance()->Get("FCPHost",m_fcphost)==false)\r
32         {\r
33                 m_fcphost="localhost";\r
34                 Option::Instance()->Set("FCPHost",m_fcphost);\r
35         }\r
36         if(Option::Instance()->Get("FCPPort",fcpport)==false)\r
37         {\r
38                 fcpport="9481";\r
39                 Option::Instance()->Set("FCPPort",fcpport);\r
40         }\r
41 \r
42         // convert fcp port to long, and make sure it's within the valid port range\r
43         if(StringFunctions::Convert(fcpport,m_fcpport)==false)\r
44         {\r
45                 m_fcpport=9481;\r
46                 Option::Instance()->Set("FCPPort","9481");\r
47         }\r
48 \r
49         m_receivednodehello=false;\r
50 \r
51 }\r
52 \r
53 FreenetMasterThread::~FreenetMasterThread()\r
54 {\r
55 \r
56 }\r
57 \r
58 const bool FreenetMasterThread::FCPConnect()\r
59 {\r
60         // we were previosly connected, send FCPDisconnect to objects\r
61         if(m_receivednodehello==true)\r
62         {\r
63                 for(std::vector<IFCPConnected *>::iterator i=m_fcpconnected.begin(); i!=m_fcpconnected.end(); i++)\r
64                 {\r
65                         (*i)->FCPDisconnected();\r
66                 }\r
67                 m_receivednodehello=false;\r
68         }\r
69 \r
70         m_log->WriteLog(LogFile::LOGLEVEL_INFO,"FreenetMasterThread::FCPConnect trying to connect to node "+m_fcphost);\r
71 \r
72         if(m_fcp.Connect(m_fcphost.c_str(),m_fcpport)==true)\r
73         {\r
74                 UUIDGenerator uuid;\r
75                 std::string clientname="FMSClient-"+uuid.Generate();\r
76                 // send ClientHello message to node\r
77                 m_fcp.SendMessage("ClientHello",2,"Name",clientname.c_str(),"ExpectedVersion","2.0");\r
78 \r
79                 m_log->WriteLog(LogFile::LOGLEVEL_INFO,"FreenetMasterThread::FCPConnect connected to node");\r
80 \r
81                 return true;\r
82         }\r
83         else\r
84         {\r
85                 return false;\r
86         }\r
87 \r
88 }\r
89 \r
90 const bool FreenetMasterThread::HandleMessage(FCPMessage &message)\r
91 {\r
92         if(message.GetName()=="NodeHello")\r
93         {\r
94                 m_receivednodehello=true;\r
95 \r
96                 // send connected message to all objects, must do this AFTER we received the NodeHello message\r
97                 for(std::vector<IFCPConnected *>::iterator i=m_fcpconnected.begin(); i!=m_fcpconnected.end(); i++)\r
98                 {\r
99                         (*i)->FCPConnected();\r
100                 }\r
101 \r
102                 return true;\r
103         }\r
104         if(m_receivednodehello==true)\r
105         {\r
106                 bool handled=false;\r
107                 std::vector<IFCPMessageHandler *>::iterator i=m_fcpmessagehandlers.begin();\r
108                 while(handled==false && i!=m_fcpmessagehandlers.end())\r
109                 {\r
110                         handled=(*i)->HandleMessage(message);\r
111                         i++;\r
112                 }\r
113 \r
114                 if(handled==false)\r
115                 {\r
116                         std::string info("");\r
117                         for(std::map<std::string,std::string>::iterator mi=message.begin(); mi!=message.end(); mi++)\r
118                         {\r
119                                 info+="\t\t\t\t"+(*mi).first+"="+(*mi).second+"\r\n";\r
120                         }\r
121                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"FreenetMasterThread::HandleMessage received unhandled "+message.GetName()+" message.  Message content :\r\n"+info);\r
122 \r
123                         // if unhandled message was alldata - we must retrieve the data\r
124                         if(message.GetName()=="AllData")\r
125                         {\r
126                                 long length;\r
127                                 StringFunctions::Convert(message["DataLength"],length);\r
128                                 while(m_fcp.Connected() && m_fcp.ReceiveBufferSize()<length)\r
129                                 {\r
130                                         m_fcp.Update(1);\r
131                                 }\r
132                                 if(m_fcp.Connected())\r
133                                 {\r
134                                         char *data=new char[length];\r
135                                         m_fcp.ReceiveRaw(data,length);\r
136                                         delete [] data;\r
137                                 }\r
138                         }\r
139                 }\r
140 \r
141                 return handled;\r
142 \r
143         }\r
144         else\r
145         {\r
146                 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"FreenetMasterThread::HandleMessage received "+message.GetName()+" message before NodeHello");\r
147         }\r
148 \r
149         return false;\r
150 }\r
151 \r
152 void FreenetMasterThread::RegisterFCPConnected(IFCPConnected *obj)\r
153 {\r
154         m_fcpconnected.push_back(obj);\r
155 }\r
156 \r
157 void FreenetMasterThread::RegisterFCPMessageHandler(IFCPMessageHandler *obj)\r
158 {\r
159         m_fcpmessagehandlers.push_back(obj);\r
160 }\r
161 \r
162 void FreenetMasterThread::RegisterPeriodicProcessor(IPeriodicProcessor *obj)\r
163 {\r
164         m_processors.push_back(obj);\r
165 }\r
166 \r
167 void FreenetMasterThread::Run()\r
168 {\r
169 \r
170         FCPMessage message;\r
171         bool done=false;\r
172 \r
173         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"FreenetMasterThread::run thread started.");\r
174 \r
175         Setup();\r
176 \r
177         do\r
178         {\r
179                 if(m_fcp.Connected()==false)\r
180                 {\r
181                         if(FCPConnect()==false)\r
182                         {\r
183 \r
184                                 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"FreenetMasterThread::run could not connect to node.  Waiting 60 seconds.");\r
185 \r
186                                 // wait 60 seconds - will then try to connect again\r
187                                 /*\r
188                                 try\r
189                                 {\r
190                                         ZThread::Thread::sleep(60000);\r
191                                 }\r
192                                 catch(...)\r
193                                 {\r
194                                         done=true;\r
195                                 }\r
196                                 */\r
197                                 for(int i=0; i<60 && !IsCancelled(); i++)\r
198                                 {\r
199                                         Sleep(1000);\r
200                                 }\r
201                         }\r
202                 }\r
203                 // fcp is connected\r
204                 else\r
205                 {\r
206                         m_fcp.Update(1);\r
207 \r
208                         // check for message on receive buffer and handle it\r
209                         if(m_fcp.ReceiveBufferSize()>0)\r
210                         {\r
211                                 message.Reset();\r
212                                 message=m_fcp.ReceiveMessage();\r
213 \r
214                                 if(message.GetName()!="")\r
215                                 {\r
216                                         HandleMessage(message);\r
217                                 }\r
218                         }\r
219 \r
220                         // let objects do their processing\r
221                         for(std::vector<IPeriodicProcessor *>::iterator i=m_processors.begin(); i!=m_processors.end(); i++)\r
222                         {\r
223                                 (*i)->Process();\r
224                         }\r
225 \r
226                 }\r
227 //      }while(!ZThread::Thread::interrupted() && done==false);\r
228         }while(!IsCancelled() && done==false);\r
229 \r
230         m_fcp.Disconnect();\r
231 \r
232         Shutdown();\r
233 \r
234         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"FreenetMasterThread::run thread exiting.");\r
235 \r
236 }\r
237 \r
238 void FreenetMasterThread::Setup()\r
239 {\r
240 \r
241         // seed random number generator\r
242         srand(time(NULL));\r
243 \r
244         m_registrables.push_back(new UnkeyedIDCreator(&m_fcp));\r
245         m_registrables.push_back(new IdentityInserter(&m_fcp));\r
246         m_registrables.push_back(new IdentityRequester(&m_fcp));\r
247         m_registrables.push_back(new IntroductionPuzzleInserter(&m_fcp));\r
248         m_registrables.push_back(new IdentityIntroductionRequester(&m_fcp));\r
249         m_registrables.push_back(new IntroductionPuzzleRequester(&m_fcp));\r
250         m_registrables.push_back(new IdentityIntroductionInserter(&m_fcp));\r
251         m_registrables.push_back(new TrustListInserter(&m_fcp));\r
252         m_registrables.push_back(new TrustListRequester(&m_fcp));\r
253         m_registrables.push_back(new MessageListRequester(&m_fcp));\r
254         m_registrables.push_back(new MessageRequester(&m_fcp));\r
255         m_registrables.push_back(new MessageInserter(&m_fcp));\r
256         m_registrables.push_back(new MessageListInserter(&m_fcp));\r
257         m_registrables.push_back(new PeriodicDBMaintenance());\r
258 \r
259         for(std::vector<IFreenetRegistrable *>::iterator i=m_registrables.begin(); i!=m_registrables.end(); i++)\r
260         {\r
261                 (*i)->RegisterWithThread(this);\r
262         }\r
263 \r
264 }\r
265 \r
266 void FreenetMasterThread::Shutdown()\r
267 {\r
268         // delete each registrable object\r
269         for(std::vector<IFreenetRegistrable *>::iterator i=m_registrables.begin(); i!=m_registrables.end(); i++)\r
270         {\r
271                 delete (*i);\r
272         }\r
273 }\r