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