00001
00007 #include "at_startup.H"
00008
00009
00010 #ifdef IS_CLIENT
00011 #error "The server is not a client!"
00012 #endif
00013
00014 #ifndef IS_SERVER
00015 #error "The server needs IS_SERVER to function correctly!"
00016 #endif
00017
00018 #ifndef USE_NETWORK
00019 #error "The server uses network features!"
00020 #endif
00021
00022 #ifdef IS_STANDALONE
00023 #error "The server is not standalone!"
00024 #endif
00025
00026
00027
00028 extern "C"
00029 {
00030 #include <unistd.h>
00031 }
00032
00033 #include <cstdio>
00034 #include <cstdlib>
00035 #include <fstream>
00036 #include <sstream>
00037 #include <cmath>
00038 #include <gmp.h>
00039 #include <list>
00040 #include <set>
00041 #include <ctime>
00042
00043 #include "qsieve.H"
00044 #include "StaticFactorbase.H"
00045
00046
00047 #include "FactorFound.H"
00048 TFoundFactors FoundFactors;
00049
00050 #include <vector>
00051 #include <stack>
00052 #include <algorithm>
00053
00054 extern "C"
00055 {
00056 #include <sys/utsname.h>
00057 #include <pthread.h>
00058 }
00059
00060 #include <csignal>
00061 #include "mutex.H"
00062
00063
00064
00065 const string RecoveryFile = "recovery.dat";
00066 const string FoundFactorsFile = "FoundFactors.dat";
00067 const string StaticRelationsFile = "static_relations.dat";
00068 const string SpecialRelationsFile = "special_relations.dat";
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 filebuf Recovery_buffer;
00084 ostream Recovery_to_file (&Recovery_buffer);
00085 istream Recovery_from_file (&Recovery_buffer);
00086
00087
00088 #include "mpqsPolynom.H"
00089
00090
00091 mpz_t n,
00092 kN;
00093
00094
00095 #include "StaticRelations.H"
00096 #include "DynamicRelations.H"
00097 #include "SpecialRelations.H"
00098
00099 #include "Sieving.H"
00100 #include "ConfigFile.cc"
00101
00102
00103 CmpqsPolynom Polynom;
00104 #include "mpqsStatistics.cc"
00105
00106
00107 #include "modulo.H"
00108 using namespace numtheory;
00109
00110 #include "FactorFound.cc"
00111 #include "polynomial.H"
00112 #include "fft_param.cc"
00113 #include "elliptic_curve.H"
00114 #include "elliptic_curve-variant.cc"
00115
00116 #include "ExitManager.cc"
00117 #include "StaticRelations.cc"
00118
00119
00120
00121 #include "easy_factor.H"
00122
00123
00124 #include "CRelation-inc.cc"
00125
00126
00127 #include "parse_term.cc"
00128
00129 const bool without_multi_combine_init = false;
00130
00131
00132 #include "SpecialRelations.cc"
00133
00134
00135 #include "Cprocess_clients.cc"
00136 #include "XML_StatusServer.cc"
00137
00138
00139
00140 void kill_all_other_threads()
00141 {
00142
00143
00144 }
00145
00146
00147
00148 void cleanup_files()
00149 {
00150 #ifdef VERBOSE_INFO
00151 cout << "cleaning files..." << endl;
00152 #endif
00153 StaticRelations::cleanup_files();
00154 SpecialRelations::cleanup_files();
00155 DynamicRelations::cleanup_files();
00156 Recovery_buffer.close();
00157 remove(RecoveryFile.c_str());
00158 }
00159
00160 void cleanup_memory()
00161 {
00162 #ifdef VERBOSE_INFO
00163 cout << "cleanup allocated memory" << endl;
00164 #endif
00165 StaticRelations::cleanup_memory();
00166 mpz_clear(CmpqsFactor::DLP_Threshold);
00167 mpz_clear(kN); mpz_clear(n);
00168 }
00169
00170
00171 void signalhandler(int signr)
00172 {
00173 #ifdef VERBOSE_WARN
00174 cout << "Signal " << signr << " received. (ThreadId=" << pthread_self() << ")" << endl;
00175 #endif
00176 exit(1);
00177 }
00178
00179
00180
00181
00182 int main(const int argc, const char* const argv[])
00183 {
00184
00185 #ifdef USE_NCURSES
00186 new Cncursed();
00187 #endif
00188
00189 PrintHeader("Qsieve server");
00190
00191 if (argc>2)
00192 {
00193 cerr << "number for factorization expected!" << endl;
00194 exit(1);
00195 }
00196
00197 const bool recover = (argc==1);
00198
00199 atexit(kill_all_other_threads);
00200 cout.setf(ios::fixed);
00201
00202 mpz_init(n);
00203 mpz_init(kN);
00204 ExitManager::register_exithandler(cleanup_memory);
00205
00206 Read_ConfigFile();
00207
00208
00209
00210
00211 const connection_waiter my_connection_waiter(server_port);
00212
00213 if (!recover)
00214 {
00215
00216 char* const neuer_str = strdup(argv[1]);
00217 char* str = neuer_str;
00218 if (!parse_term::get_number(n, str))
00219 {
00220 cout << "Wrong input at: '" << str << "'" << endl;
00221 exit(1);
00222 }
00223 else
00224 if (str[0]!='\0')
00225 {
00226 cout << "Syntax error in input term. (parenthesis?)" << endl;
00227 exit(1);
00228 }
00229 else
00230 if (mpz_cmp_ui(n,0)<=0)
00231 {
00232 cout << "Input must be positive natural number!" << endl;
00233 exit(1);
00234 }
00235 free(neuer_str);
00236 FoundFactors.regarding=argv[1];
00237 mpz_set(FoundFactors.regarding_numeric_value,n);
00238 }
00239
00240 if (recover)
00241 {
00242
00243
00244 StaticRelations::FileBuffer.open(StaticRelationsFile.c_str(),ios::in|ios::out);
00245 SpecialRelations::FileBuffer.open(SpecialRelationsFile.c_str(),ios::in|ios::out);
00246 if (!DynamicRelations::FileBuffer.open(DynamicRelationsFile.c_str(),ios::in|ios::out))
00247 {
00248 cerr << "Cannot access " << DynamicRelationsFile << endl;
00249 exit(1);
00250 }
00251 Recovery_buffer.open(RecoveryFile.c_str(),ios::in|ios::out|ios::ate);
00252
00253
00254
00255 if (Recovery_from_file) Recovery_from_file.seekg(0,ios::end);
00256 #ifdef STL_STREAM_workaround
00257 if ( (!Recovery_from_file) || (Recovery_from_file.tellg()==std::streampos(0)) || (Recovery_from_file.tellg()==std::streampos(-1)) )
00258
00259
00260
00261
00262
00263 #else
00264 if ( (!Recovery_from_file) || (Recovery_from_file.tellg()<1) )
00265 #endif
00266 {
00267 cerr << "Recovery not possible!" << endl;
00268 exit(1);
00269 }
00270
00271 Recovery_from_file.seekg(0,ios::beg);
00272 Recovery_to_file.seekp(0,ios::beg);
00273 Recovery_from_file >> n;
00274 Recovery_from_file.ignore(1,'\n');
00275
00276 cout << "Continue factorization for " << endl;
00277 cout << n << endl;
00278
00279
00280
00281 Factorization_to_file << " [RECOVERY] ";
00282 FoundFactors.AutoLoad();
00283 }
00284 else
00285 {
00286
00287
00288 StaticRelations::FileBuffer.open(StaticRelationsFile.c_str(),ios::out|ios::trunc);
00289 SpecialRelations::FileBuffer.open(SpecialRelationsFile.c_str(),ios::in|ios::out|ios::trunc);
00290 if (!DynamicRelations::FileBuffer.open(DynamicRelationsFile.c_str(),ios::in|ios::out|ios::trunc))
00291 {
00292 cerr << "Cannot access " << DynamicRelationsFile << endl;
00293 exit(1);
00294 }
00295
00296 Recovery_buffer.open(RecoveryFile.c_str(),ios::in|ios::out|ios::trunc);
00297
00298 cout_status << "Starting factorization for" << endl;
00299 cout_status << n << endl;
00300
00301 Factorization_to_file << endl << "Factorization of " << argv[1] << ":" << endl;
00302 Factorization_to_file << n << " = " << endl;
00303
00304 easy_factor();
00305
00306 #ifdef VERBOSE_NOTICE
00307 cout_status << "Starting factorization with ECM and MPQS for" << endl;
00308 cout_status << n << endl;
00309 #endif
00310 Recovery_to_file << n << endl;
00311 unlink("ecm-recover.dat");
00312 }
00313 ExitManager::register_exithandler(cleanup_files);
00314
00315 signal(SIGINT, signalhandler);
00316 tune_parameters(mpz_sizeinbase(n,10));
00317
00318 #ifdef NOTIFY_PARENT
00319
00320
00321 kill(getppid(),SIGUSR1);
00322 #endif
00323
00324 CXML_StatusServer::install_XML_StatusServer();
00325 if (!SkipECM)
00326 {
00327 #ifdef VERBOSE_NOTICE
00328 cout << "Waiting for net-clients (ECM)..." << endl;
00329 #endif
00330 Cprocess_clients::process_data_stream_ecm(my_connection_waiter);
00331 }
00332
00333
00334 #if defined(USE_DFT) || (CONTINUATION_METHOD==2)
00335
00336
00337
00338 polynomial::clear_dft_tempmemory();
00339 #endif
00340
00341
00342
00343 determine_best_MPQS_Multiplier(n,kN,MPQS_Multiplier);
00344 tune_parameters(mpz_sizeinbase(n,10));
00345
00346
00347
00348 if ( sqrt(mpz_get_d(kN)) < PhysicalSieveSize )
00349 {
00350 cerr << "Sieve size too big (you may want to reduce its size)!" << endl;
00351 exit(1);
00352 }
00353
00354
00355
00356 mpz_init(CmpqsFactor::DLP_Threshold);
00357 mpz_set_ui(CmpqsFactor::DLP_Threshold,SingleLargePrime_Threshold);
00358 mpz_mul(CmpqsFactor::DLP_Threshold,CmpqsFactor::DLP_Threshold,CmpqsFactor::DLP_Threshold);
00359
00360 StaticFactorbase::compute_StaticFactorbase();
00361
00362
00363
00364
00365
00366 Polynom.compute_first_polynomial(kN,LogicalSieveSize);
00367
00368
00369 if (recover)
00370 {
00371 StaticRelations::Load();
00372 DynamicRelations::Load();
00373 SpecialRelations::Load();
00374 statistical_data::ProgressStats.take_sample();
00375
00376
00377
00378 SpecialRelations::CycleSearch();
00379
00380 #ifdef SAFEMODE
00381
00382 CRelation::SanityCheckRelationsFile(StaticRelationsFile);
00383 CRelation::SanityCheckRelationsFile(DynamicRelationsFile);
00384 CRelation::SanityCheckRelationsFile(SpecialRelationsFile);
00385 #endif
00386 streampos fpos = Recovery_from_file.tellg();
00387 Polynom.load_if_available(Recovery_from_file);
00388 Recovery_to_file.seekp(fpos);
00389 }
00390
00391 display_StatusLegend();
00392
00393
00394 CRelation::seek_emergency_handler = Cprocess_clients::seek_emergency_handler;
00395
00396 #ifdef VERBOSE_NOTICE
00397 cout << "Waiting for clients (MPQS)..." << endl;
00398 #endif
00399
00400 while (true)
00401 {
00402 int* pdata = new int;
00403 *pdata = my_connection_waiter.get_new_client_socket_descriptor();
00404 pthread_attr_t detached_thread;
00405 pthread_t thread_process_client_data;
00406
00407 pthread_attr_init(&detached_thread);
00408 pthread_attr_setdetachstate(&detached_thread, PTHREAD_CREATE_DETACHED);
00409
00410
00411 const int retcode = pthread_create(&thread_process_client_data,&detached_thread,
00412 Cprocess_clients::THREAD_process_data_stream, pdata);
00413 if (retcode != 0)
00414 {
00415 cerr << "pthread_create failed!" << endl;
00416 delete pdata;
00417 exit(1);
00418 }
00419 }
00420
00421
00422
00423 #ifdef VERBOSE_INFO
00424 cout << endl << "Session ended successfully." << endl;
00425 #endif
00426 return 0;
00427 }