gnunet-ats-solver-eval.c 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2010-2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file ats-tests/ats-testing-experiment.c
  19. * @brief ats benchmark: controlled experiment execution
  20. * @author Christian Grothoff
  21. * @author Matthias Wachs
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet-ats-solver-eval.h"
  26. #include "gnunet-service-ats_normalization.h"
  27. #include "gnunet-service-ats_preferences.c"
  28. #define BIG_M_STRING "unlimited"
  29. /**
  30. * Handle for statistics.
  31. */
  32. struct GNUNET_STATISTICS_Handle *GSA_stats;
  33. static struct Experiment *e;
  34. static struct LoggingHandle *l;
  35. static struct SolverHandle *sh;
  36. static struct TestPeer *peer_head;
  37. static struct TestPeer *peer_tail;
  38. static double default_properties[GNUNET_ATS_PropertyCount];
  39. static double default_preferences[GNUNET_ATS_PreferenceCount];
  40. /**
  41. * cmd option -e: experiment file
  42. */
  43. static char *opt_exp_file;
  44. static char *opt_solver;
  45. /**
  46. * cmd option -l: enable logging
  47. */
  48. static int opt_log;
  49. /**
  50. * cmd option -p: enable plots
  51. */
  52. static int opt_save;
  53. /**
  54. * cmd option -v: verbose logs
  55. */
  56. static int opt_verbose;
  57. /**
  58. * cmd option -p: print logs
  59. */
  60. static int opt_print;
  61. /**
  62. * cmd option -d: disable normalization
  63. */
  64. static int opt_disable_normalization;
  65. static int res;
  66. static void
  67. end_now ();
  68. static char *
  69. print_generator_type (enum GeneratorType g)
  70. {
  71. switch (g) {
  72. case GNUNET_ATS_TEST_TG_CONSTANT:
  73. return "CONSTANT";
  74. case GNUNET_ATS_TEST_TG_LINEAR:
  75. return "LINEAR";
  76. case GNUNET_ATS_TEST_TG_RANDOM:
  77. return "RANDOM";
  78. case GNUNET_ATS_TEST_TG_SINUS:
  79. return "SINUS";
  80. default:
  81. return "INVALID";
  82. break;
  83. }
  84. }
  85. static struct TestPeer *
  86. find_peer_by_id (int id)
  87. {
  88. struct TestPeer *cur;
  89. for (cur = peer_head; NULL != cur; cur = cur->next)
  90. if (cur->id == id)
  91. return cur;
  92. return NULL;
  93. }
  94. static struct TestPeer *
  95. find_peer_by_pid (const struct GNUNET_PeerIdentity *pid)
  96. {
  97. struct TestPeer *cur;
  98. for (cur = peer_head; NULL != cur; cur = cur->next)
  99. if (0 == memcmp (&cur->peer_id, pid, sizeof (struct GNUNET_PeerIdentity)))
  100. return cur;
  101. return NULL;
  102. }
  103. static struct TestAddress *
  104. find_address_by_id (struct TestPeer *peer, int aid)
  105. {
  106. struct TestAddress *cur;
  107. for (cur = peer->addr_head; NULL != cur; cur = cur->next)
  108. if (cur->aid == aid)
  109. return cur;
  110. return NULL;
  111. }
  112. /**
  113. * Logging
  114. */
  115. void
  116. GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
  117. {
  118. struct LoggingTimeStep *lts;
  119. struct TestPeer *cur;
  120. struct TestAddress *cur_addr;
  121. struct LoggingPeer *log_p;
  122. struct LoggingAddress *log_a;
  123. int c;
  124. lts = GNUNET_new (struct LoggingTimeStep);
  125. GNUNET_CONTAINER_DLL_insert_tail(l->head, l->tail, lts);
  126. lts->timestamp = GNUNET_TIME_absolute_get();
  127. if (NULL == lts->prev)
  128. lts->delta = GNUNET_TIME_UNIT_ZERO;
  129. else
  130. lts->delta = GNUNET_TIME_absolute_get_duration(lts->prev->timestamp);
  131. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging %llu, delta %llu\n",
  132. lts->timestamp.abs_value_us, lts->delta.rel_value_us);
  133. /* Store logging data here */
  134. for (cur = peer_head; NULL != cur; cur = cur->next)
  135. {
  136. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  137. "Logging peer id %llu\n", cur->id);
  138. log_p = GNUNET_new (struct LoggingPeer);
  139. log_p->id = cur->id;
  140. log_p->peer_id = cur->peer_id;
  141. log_p->is_requested = cur->is_requested;
  142. for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
  143. {
  144. log_p->pref_abs[c] = cur->pref_abs[c];
  145. log_p->pref_norm[c] = cur->pref_norm[c];
  146. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  147. "\t %s = %.2f %.2f [abs/rel]\n",
  148. GNUNET_ATS_print_preference_type(c),
  149. log_p->pref_abs[c], log_p->pref_norm[c]);
  150. }
  151. GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p);
  152. for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
  153. {
  154. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  155. "Logging peer id %llu address %llu\n",
  156. cur->id, cur_addr->aid);
  157. log_a = GNUNET_new (struct LoggingAddress);
  158. log_a->aid = cur_addr->aid;
  159. log_a->active = cur_addr->ats_addr->active;
  160. log_a->network = cur_addr->network;
  161. log_a->assigned_bw_in = cur_addr->ats_addr->assigned_bw_in;
  162. log_a->assigned_bw_out = cur_addr->ats_addr->assigned_bw_out;
  163. for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
  164. {
  165. log_a->prop_abs[c] = cur_addr->prop_abs[c];
  166. log_a->prop_norm[c] = cur_addr->prop_norm[c];
  167. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  168. "\t %s = %.2f %.2f [abs/rel]\n",
  169. GNUNET_ATS_print_property_type(c),
  170. log_a->prop_abs[c],
  171. log_a->prop_norm[c]);
  172. }
  173. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
  174. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", log_a->assigned_bw_in);
  175. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "\t BW out = %llu\n", log_a->assigned_bw_out);
  176. GNUNET_CONTAINER_DLL_insert_tail (log_p->addr_head, log_p->addr_tail, log_a);
  177. }
  178. }
  179. }
  180. static void
  181. logging_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  182. {
  183. struct LoggingHandle *l = cls;
  184. l->logging_task = NULL;
  185. GNUNET_ATS_solver_logging_now (l);
  186. l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq,
  187. &logging_task,
  188. l);
  189. }
  190. struct LoggingHandle *
  191. GNUNET_ATS_solver_logging_start (struct GNUNET_TIME_Relative freq)
  192. {
  193. struct LoggingHandle *l;
  194. l = GNUNET_new (struct LoggingHandle);
  195. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start logging every %s\n",
  196. GNUNET_STRINGS_relative_time_to_string(freq, GNUNET_NO));
  197. l->log_freq = freq;
  198. l->logging_task = GNUNET_SCHEDULER_add_now (&logging_task, l);
  199. return l;
  200. }
  201. void
  202. GNUNET_ATS_solver_logging_stop (struct LoggingHandle *l)
  203. {
  204. if (NULL != l->logging_task)
  205. GNUNET_SCHEDULER_cancel (l->logging_task);
  206. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop logging\n");
  207. l->logging_task = NULL;
  208. }
  209. static struct LoggingFileHandle *
  210. find_logging_file_handle (struct LoggingFileHandle *lf_head,
  211. struct LoggingFileHandle *lf_tail,
  212. int peer_id, int address_id)
  213. {
  214. struct LoggingFileHandle *res;
  215. for (res = lf_head; NULL != res; res = res->next)
  216. if ((res->pid == peer_id) && (res->aid == address_id))
  217. return res;
  218. return NULL;
  219. }
  220. void
  221. GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int add_time_stamp,
  222. char *output_dir)
  223. {
  224. struct LoggingTimeStep *lts;
  225. struct LoggingPeer *log_p;
  226. struct LoggingAddress *log_a;
  227. struct LoggingFileHandle *lf_head;
  228. struct LoggingFileHandle *lf_tail;
  229. struct LoggingFileHandle *cur;
  230. struct LoggingFileHandle *next;
  231. char * filename;
  232. char * datastring;
  233. char * propstring;
  234. char * propstring_tmp;
  235. char * prefstring;
  236. char * prefstring_tmp;
  237. int c;
  238. int use_dir;
  239. use_dir = GNUNET_NO;
  240. if (NULL != output_dir)
  241. {
  242. if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (output_dir))
  243. {
  244. fprintf (stderr, "Failed to create directory `%s'\n", output_dir);
  245. return;
  246. }
  247. else
  248. {
  249. fprintf (stderr, "Created directory `%s'\n", output_dir);
  250. use_dir = GNUNET_YES;
  251. }
  252. }
  253. lf_head = NULL;
  254. lf_tail = NULL;
  255. for (lts = l->head; NULL != lts; lts = lts->next)
  256. {
  257. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing log step %llu\n",
  258. (long long unsigned int) lts->timestamp.abs_value_us);
  259. for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
  260. {
  261. for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
  262. {
  263. cur = find_logging_file_handle (lf_head, lf_tail, log_p->id,
  264. log_a->aid);
  265. if (NULL == cur)
  266. {
  267. cur = GNUNET_new (struct LoggingFileHandle);
  268. cur->aid = log_a->aid;
  269. cur->pid = log_p->id;
  270. if (GNUNET_YES == add_time_stamp)
  271. GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u_%llu.log",
  272. (GNUNET_YES == use_dir) ? output_dir : "",
  273. (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
  274. e->log_prefix,
  275. opt_solver,
  276. cur->pid,
  277. cur->aid,
  278. l->head->timestamp.abs_value_us);
  279. else
  280. GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u.log",
  281. (GNUNET_YES == use_dir) ? output_dir : "",
  282. (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
  283. e->log_prefix,
  284. opt_solver,
  285. cur->pid,
  286. cur->aid);
  287. fprintf (stderr, "Add writing log data for peer %llu address %llu to file `%s'\n",
  288. cur->pid, cur->aid, filename);
  289. cur->f_hd = GNUNET_DISK_file_open (filename,
  290. GNUNET_DISK_OPEN_READWRITE |
  291. GNUNET_DISK_OPEN_CREATE |
  292. GNUNET_DISK_OPEN_TRUNCATE,
  293. GNUNET_DISK_PERM_USER_READ |
  294. GNUNET_DISK_PERM_USER_WRITE |
  295. GNUNET_DISK_PERM_GROUP_READ |
  296. GNUNET_DISK_PERM_OTHER_READ);
  297. if (NULL == cur->f_hd)
  298. {
  299. fprintf (stderr, "Cannot open `%s' to write log data!\n", filename);
  300. GNUNET_free (filename);
  301. GNUNET_free (cur);
  302. goto cleanup;
  303. }
  304. GNUNET_free (filename);
  305. GNUNET_CONTAINER_DLL_insert (lf_head, lf_tail, cur);
  306. GNUNET_asprintf(&datastring,"#time delta;log duration;peer_requested;addr net; addr_active; bw in; bw out; " \
  307. "UTILIZATION_UP [abs/rel]; UTILIZATION_UP; UTILIZATION_DOWN; UTILIZATION_DOWN; " \
  308. "UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_DOWN; UTILIZATION_PAYLOAD_DOWN;"\
  309. "DELAY; DELAY; " \
  310. "DISTANCE ;DISTANCE ; COST_WAN; COST_WAN; COST_LAN; COST_LAN; " \
  311. "COST_WLAN; COST_WLAN;COST_BT; COST_BT; PREF BW abs; PREF BW rel; PREF LATENCY abs; PREF LATENCY rel;\n");
  312. GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
  313. GNUNET_free (datastring);
  314. }
  315. prefstring = GNUNET_strdup("");
  316. for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
  317. {
  318. /*
  319. fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
  320. GNUNET_ATS_print_preference_type(c),
  321. log_p->pref_abs[c], log_p->pref_norm[c]);
  322. */
  323. GNUNET_asprintf(&prefstring_tmp,"%s;%.3f;%.3f",
  324. prefstring, log_p->pref_abs[c], log_p->pref_norm[c]);
  325. GNUNET_free (prefstring);
  326. prefstring = GNUNET_strdup(prefstring_tmp);
  327. GNUNET_free (prefstring_tmp);
  328. }
  329. propstring = GNUNET_strdup("");
  330. for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
  331. {
  332. if (GNUNET_ATS_NETWORK_TYPE == c)
  333. continue;
  334. /*
  335. fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
  336. GNUNET_ATS_print_property_type(c),
  337. log_a->prop_abs[c], log_a->prop_norm[c]);*/
  338. GNUNET_asprintf(&propstring_tmp,"%s%.3f;%.3f;",
  339. propstring,
  340. log_a->prop_abs[c],
  341. log_a->prop_norm[c]);
  342. GNUNET_free (propstring);
  343. propstring = GNUNET_strdup(propstring_tmp);
  344. GNUNET_free (propstring_tmp);
  345. }
  346. GNUNET_asprintf (&datastring, "%llu;%llu;%u;%u;%i;%u;%u;%s;%s\n",
  347. GNUNET_TIME_absolute_get_difference (l->head->timestamp,
  348. lts->timestamp).rel_value_us / 1000, lts->delta,
  349. log_p->is_requested, log_a->network, log_a->active,
  350. log_a->assigned_bw_in, log_a->assigned_bw_out, propstring,
  351. prefstring);
  352. GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
  353. GNUNET_free (datastring);
  354. GNUNET_free (prefstring);
  355. GNUNET_free (propstring);
  356. }
  357. }
  358. }
  359. cleanup:
  360. next = lf_head;
  361. for (cur = next; NULL != cur; cur = next)
  362. {
  363. next = cur->next;
  364. GNUNET_CONTAINER_DLL_remove (lf_head, lf_tail, cur);
  365. if (NULL != cur->f_hd)
  366. GNUNET_DISK_file_close (cur->f_hd);
  367. GNUNET_free (cur);
  368. }
  369. }
  370. void
  371. GNUNET_ATS_solver_logging_eval (struct LoggingHandle *l)
  372. {
  373. struct LoggingTimeStep *lts;
  374. struct LoggingPeer *log_p;
  375. struct LoggingAddress *log_a;
  376. int c;
  377. for (lts = l->head; NULL != lts; lts = lts->next)
  378. {
  379. fprintf (stderr, "Log step %llu %llu: \n",
  380. (long long unsigned int) lts->timestamp.abs_value_us,
  381. (long long unsigned int) lts->delta.rel_value_us);
  382. for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
  383. {
  384. fprintf (stderr,"\tLogging peer pid %llu\n", log_p->id);
  385. for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
  386. {
  387. fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
  388. GNUNET_ATS_print_preference_type(c),
  389. log_p->pref_abs[c], log_p->pref_norm[c]);
  390. }
  391. for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
  392. {
  393. fprintf (stderr, "\tPeer pid %llu address %llu: %u %u %u\n",
  394. log_p->id, log_a->aid, log_a->active,
  395. log_a->assigned_bw_in,
  396. log_a->assigned_bw_out);
  397. for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
  398. {
  399. if (GNUNET_ATS_NETWORK_TYPE == c)
  400. continue;
  401. fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
  402. GNUNET_ATS_print_property_type(c),
  403. log_a->prop_abs[c], log_a->prop_norm[c]);
  404. }
  405. }
  406. }
  407. }
  408. }
  409. void
  410. GNUNET_ATS_solver_logging_free (struct LoggingHandle *l)
  411. {
  412. struct LoggingTimeStep *lts_cur;
  413. struct LoggingTimeStep *lts_next;
  414. struct LoggingPeer *log_p_cur;
  415. struct LoggingPeer *log_p_next;
  416. struct LoggingAddress *log_a_cur;
  417. struct LoggingAddress *log_a_next;
  418. if (NULL != l->logging_task)
  419. GNUNET_SCHEDULER_cancel (l->logging_task);
  420. l->logging_task = NULL;
  421. lts_next = l->head;
  422. while (NULL != (lts_cur = lts_next))
  423. {
  424. lts_next = lts_cur->next;
  425. log_p_next = lts_cur->head;
  426. while (NULL != (log_p_cur = log_p_next))
  427. {
  428. log_p_next = log_p_cur->next;
  429. log_a_next = log_p_cur->addr_head;
  430. while (NULL != (log_a_cur = log_a_next))
  431. {
  432. log_a_next = log_a_cur->next;
  433. GNUNET_CONTAINER_DLL_remove (log_p_cur->addr_head, log_p_cur->addr_tail, log_a_cur);
  434. GNUNET_free (log_a_cur);
  435. }
  436. GNUNET_CONTAINER_DLL_remove (lts_cur->head, lts_cur->tail, log_p_cur);
  437. GNUNET_free (log_p_cur);
  438. }
  439. GNUNET_CONTAINER_DLL_remove (l->head, l->tail, lts_cur);
  440. GNUNET_free (lts_cur);
  441. }
  442. GNUNET_free (l);
  443. }
  444. /**
  445. * Property Generators
  446. */
  447. static struct PropertyGenerator *prop_gen_head;
  448. static struct PropertyGenerator *prop_gen_tail;
  449. static double
  450. get_property (struct PropertyGenerator *pg)
  451. {
  452. struct GNUNET_TIME_Relative time_delta;
  453. double delta_value;
  454. double pref_value;
  455. /* Calculate the current preference value */
  456. switch (pg->type) {
  457. case GNUNET_ATS_TEST_TG_CONSTANT:
  458. pref_value = pg->base_value;
  459. break;
  460. case GNUNET_ATS_TEST_TG_LINEAR:
  461. time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
  462. /* Calculate point of time in the current period */
  463. time_delta.rel_value_us = time_delta.rel_value_us %
  464. pg->duration_period.rel_value_us;
  465. delta_value = ((double) time_delta.rel_value_us /
  466. pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
  467. if ((pg->max_value < pg->base_value) &&
  468. ((pg->max_value - pg->base_value) > pg->base_value))
  469. {
  470. /* This will cause an underflow */
  471. GNUNET_break (0);
  472. }
  473. pref_value = pg->base_value + delta_value;
  474. break;
  475. case GNUNET_ATS_TEST_TG_RANDOM:
  476. delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  477. 10000 * (pg->max_value - pg->base_value)) / 10000;
  478. pref_value = pg->base_value + delta_value;
  479. break;
  480. case GNUNET_ATS_TEST_TG_SINUS:
  481. time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
  482. /* Calculate point of time in the current period */
  483. time_delta.rel_value_us = time_delta.rel_value_us %
  484. pg->duration_period.rel_value_us;
  485. if ((pg->max_value - pg->base_value) > pg->base_value)
  486. {
  487. /* This will cause an underflow for second half of sinus period,
  488. * will be detected in general when experiments are loaded */
  489. GNUNET_break (0);
  490. }
  491. delta_value = (pg->max_value - pg->base_value) *
  492. sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
  493. time_delta.rel_value_us);
  494. pref_value = pg->base_value + delta_value;
  495. break;
  496. default:
  497. pref_value = 0.0;
  498. break;
  499. }
  500. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current property value is %f\n",
  501. pref_value);
  502. return pref_value;
  503. }
  504. static void
  505. set_prop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  506. {
  507. struct PropertyGenerator *pg = cls;
  508. struct TestPeer *p;
  509. struct TestAddress *a;
  510. double prop_value;
  511. struct GNUNET_ATS_Information atsi;
  512. pg->set_task = NULL;
  513. if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains_value (sh->addresses,
  514. &pg->test_peer->peer_id, pg->test_address->ats_addr))
  515. {
  516. GNUNET_break (0);
  517. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  518. "Setting property generation for unknown address [%u:%u]\n",
  519. pg->peer, pg->address_id);
  520. return;
  521. }
  522. if (NULL == (p = find_peer_by_id (pg->peer)))
  523. {
  524. GNUNET_break (0);
  525. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  526. "Setting property generation for unknown peer %u\n",
  527. pg->peer);
  528. return;
  529. }
  530. if (NULL == (a = find_address_by_id (p, pg->address_id)))
  531. {
  532. GNUNET_break (0);
  533. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  534. "Setting property generation for unknown peer %u\n",
  535. pg->peer);
  536. return;
  537. }
  538. prop_value = get_property (pg);
  539. a->prop_abs[pg->ats_property] = prop_value;
  540. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  541. "Setting property for peer [%u] address [%u] for %s to %f\n",
  542. pg->peer, pg->address_id,
  543. GNUNET_ATS_print_property_type (pg->ats_property), prop_value);
  544. atsi.type = htonl (pg->ats_property);
  545. atsi.value = htonl ((uint32_t) prop_value);
  546. /* set performance here! */
  547. sh->sf->s_bulk_start (sh->sf->cls);
  548. if (GNUNET_YES == opt_disable_normalization)
  549. {
  550. a->prop_abs[pg->ats_property] = prop_value;
  551. a->prop_norm[pg->ats_property] = prop_value;
  552. sh->sf->s_address_update_property (sh->sf->cls, a->ats_addr,
  553. pg->ats_property, prop_value, prop_value);
  554. }
  555. else
  556. GAS_normalization_update_property (pg->test_address->ats_addr, &atsi, 1);
  557. sh->sf->s_bulk_stop (sh->sf->cls);
  558. pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
  559. &set_prop_task, pg);
  560. }
  561. /**
  562. * Set ats_property to 0 to find all pgs
  563. */
  564. static struct PropertyGenerator *
  565. find_prop_gen (unsigned int peer, unsigned int address,
  566. uint32_t ats_property)
  567. {
  568. struct PropertyGenerator *cur;
  569. for (cur = prop_gen_head; NULL != cur; cur = cur->next)
  570. if ((cur->peer == peer) && (cur->address_id == address))
  571. {
  572. if ((cur->ats_property == ats_property) || (0 == ats_property))
  573. return cur;
  574. }
  575. return NULL;
  576. }
  577. void
  578. GNUNET_ATS_solver_generate_property_stop (struct PropertyGenerator *pg)
  579. {
  580. GNUNET_CONTAINER_DLL_remove (prop_gen_head, prop_gen_tail, pg);
  581. if (NULL != pg->set_task)
  582. {
  583. GNUNET_SCHEDULER_cancel (pg->set_task);
  584. pg->set_task = NULL;
  585. }
  586. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  587. "Removing old up preference generator peer [%u] address [%u] `%s'\n",
  588. pg->peer, pg->address_id,
  589. GNUNET_ATS_print_property_type(pg->ats_property));
  590. GNUNET_free (pg);
  591. }
  592. /**
  593. * Generate between the source master and the partner and set property with a
  594. * value depending on the generator.
  595. *
  596. * @param peer source
  597. * @param address_id partner
  598. * @param test_peer the peer
  599. * @param test_address the address
  600. * @param type type of generator
  601. * @param base_value base value
  602. * @param value_rate maximum value
  603. * @param period duration of a period of generation (~ 1/frequency)
  604. * @param frequency how long to generate property
  605. * @param ats_property ATS property to generate
  606. * @return the property generator
  607. */
  608. struct PropertyGenerator *
  609. GNUNET_ATS_solver_generate_property_start (unsigned int peer,
  610. unsigned int address_id,
  611. struct TestPeer *test_peer,
  612. struct TestAddress *test_address,
  613. enum GeneratorType type,
  614. long int base_value,
  615. long int value_rate,
  616. struct GNUNET_TIME_Relative period,
  617. struct GNUNET_TIME_Relative frequency,
  618. uint32_t ats_property)
  619. {
  620. struct PropertyGenerator *pg;
  621. pg = GNUNET_new (struct PropertyGenerator);
  622. GNUNET_CONTAINER_DLL_insert (prop_gen_head, prop_gen_tail, pg);
  623. pg->type = type;
  624. pg->peer = peer;
  625. pg->test_address = test_address;
  626. pg->test_peer = test_peer;
  627. pg->address_id = address_id;
  628. pg->ats_property = ats_property;
  629. pg->base_value = base_value;
  630. pg->max_value = value_rate;
  631. pg->duration_period = period;
  632. pg->frequency = frequency;
  633. pg->time_start = GNUNET_TIME_absolute_get();
  634. switch (type) {
  635. case GNUNET_ATS_TEST_TG_CONSTANT:
  636. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  637. "Setting up %s property generator peer [%u] address [%u] `%s'"\
  638. "max %u Bips\n",
  639. print_generator_type(type), pg->peer, pg->address_id,
  640. GNUNET_ATS_print_property_type (ats_property),
  641. base_value);
  642. break;
  643. case GNUNET_ATS_TEST_TG_LINEAR:
  644. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  645. "Setting up %s property generator peer [%u] address [%u] `%s' " \
  646. "min %u Bips max %u Bips\n",
  647. print_generator_type(type), pg->peer, pg->address_id,
  648. GNUNET_ATS_print_property_type(ats_property),
  649. base_value, value_rate);
  650. break;
  651. case GNUNET_ATS_TEST_TG_SINUS:
  652. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  653. "Setting up %s property generator peer [%u] address [%u] `%s' "\
  654. "baserate %u Bips, amplitude %u Bps\n",
  655. print_generator_type(type), pg->peer, pg->address_id,
  656. GNUNET_ATS_print_property_type(ats_property),
  657. base_value, value_rate);
  658. break;
  659. case GNUNET_ATS_TEST_TG_RANDOM:
  660. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  661. "Setting up %s property generator peer [%u] address [%u] `%s' "\
  662. "min %u Bips max %u Bps\n",
  663. print_generator_type(type), pg->peer, pg->address_id,
  664. GNUNET_ATS_print_property_type(ats_property),
  665. base_value, value_rate);
  666. break;
  667. default:
  668. break;
  669. }
  670. pg->set_task = GNUNET_SCHEDULER_add_now (&set_prop_task, pg);
  671. return pg;
  672. }
  673. /**
  674. * Stop all preferences generators
  675. */
  676. void
  677. GNUNET_ATS_solver_generate_property_stop_all ()
  678. {
  679. struct PropertyGenerator *cur;
  680. struct PropertyGenerator *next;
  681. next = prop_gen_head;
  682. for (cur = next; NULL != cur; cur = next)
  683. {
  684. next = cur->next;
  685. GNUNET_ATS_solver_generate_property_stop (cur);
  686. }
  687. }
  688. /**
  689. * Preference Generators
  690. */
  691. static struct PreferenceGenerator *pref_gen_head;
  692. static struct PreferenceGenerator *pref_gen_tail;
  693. static double
  694. get_preference (struct PreferenceGenerator *pg)
  695. {
  696. struct GNUNET_TIME_Relative time_delta;
  697. double delta_value;
  698. double pref_value;
  699. /* Calculate the current preference value */
  700. switch (pg->type) {
  701. case GNUNET_ATS_TEST_TG_CONSTANT:
  702. pref_value = pg->base_value;
  703. break;
  704. case GNUNET_ATS_TEST_TG_LINEAR:
  705. time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
  706. /* Calculate point of time in the current period */
  707. time_delta.rel_value_us = time_delta.rel_value_us %
  708. pg->duration_period.rel_value_us;
  709. delta_value = ((double) time_delta.rel_value_us /
  710. pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
  711. if ((pg->max_value < pg->base_value) &&
  712. ((pg->max_value - pg->base_value) > pg->base_value))
  713. {
  714. /* This will cause an underflow */
  715. GNUNET_break (0);
  716. }
  717. pref_value = pg->base_value + delta_value;
  718. break;
  719. case GNUNET_ATS_TEST_TG_RANDOM:
  720. delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  721. 10000 * (pg->max_value - pg->base_value)) / 10000;
  722. pref_value = pg->base_value + delta_value;
  723. break;
  724. case GNUNET_ATS_TEST_TG_SINUS:
  725. time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
  726. /* Calculate point of time in the current period */
  727. time_delta.rel_value_us = time_delta.rel_value_us %
  728. pg->duration_period.rel_value_us;
  729. if ((pg->max_value - pg->base_value) > pg->base_value)
  730. {
  731. /* This will cause an underflow for second half of sinus period,
  732. * will be detected in general when experiments are loaded */
  733. GNUNET_break (0);
  734. }
  735. delta_value = (pg->max_value - pg->base_value) *
  736. sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
  737. time_delta.rel_value_us);
  738. pref_value = pg->base_value + delta_value;
  739. break;
  740. default:
  741. pref_value = 0.0;
  742. break;
  743. }
  744. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
  745. pref_value);
  746. return pref_value;
  747. }
  748. static void
  749. set_feedback_task (void *cls,
  750. const struct GNUNET_SCHEDULER_TaskContext *tc)
  751. {
  752. struct PreferenceGenerator *pg = cls;
  753. struct TestPeer *p;
  754. double feedback;
  755. uint32_t bw_acc_out;
  756. uint32_t bw_acc_in;
  757. uint32_t delay_acc_in;
  758. struct GNUNET_TIME_Relative dur;
  759. double p_new;
  760. pg->feedback_task = NULL;
  761. if (NULL == (p = find_peer_by_id (pg->peer)))
  762. {
  763. GNUNET_break (0);
  764. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  765. "Setting feedback for unknown peer %u\n", pg->peer);
  766. return;
  767. }
  768. switch (pg->kind)
  769. {
  770. case GNUNET_ATS_PREFERENCE_BANDWIDTH:
  771. dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
  772. bw_acc_in = dur.rel_value_us *pg->last_assigned_bw_in + pg->feedback_bw_in_acc;
  773. pg->feedback_bw_in_acc = 0;
  774. bw_acc_out = dur.rel_value_us *pg->last_assigned_bw_out + pg->feedback_bw_out_acc;
  775. p_new = get_preference (pg);
  776. feedback = (p_new / pg->pref_bw_old) * (bw_acc_in + bw_acc_out) /
  777. (2 *GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
  778. break;
  779. case GNUNET_ATS_PREFERENCE_LATENCY:
  780. dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_delay_update);
  781. delay_acc_in =dur.rel_value_us *pg->last_delay_value + pg->feedback_delay_acc;
  782. pg->feedback_delay_acc = 0;
  783. p_new = get_preference (pg);
  784. feedback = (p_new / pg->pref_latency_old) * (delay_acc_in) /
  785. (GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
  786. break;
  787. default:
  788. GNUNET_break (0);
  789. feedback = 0.0;
  790. break;
  791. }
  792. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  793. "Giving feedback for peer [%u] for client %p pref %s of %.3f\n",
  794. pg->peer, NULL + (pg->client_id),
  795. GNUNET_ATS_print_preference_type (pg->kind),
  796. feedback);
  797. sh->sf->s_feedback (sh->sf->cls, NULL + (pg->client_id), &p->peer_id,
  798. pg->feedback_frequency, pg->kind, feedback);
  799. pg->feedback_last = GNUNET_TIME_absolute_get();
  800. pg->feedback_bw_out_acc = 0;
  801. pg->feedback_bw_in_acc = 0;
  802. pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
  803. pg->feedback_delay_acc = 0;
  804. pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
  805. pg->feedback_task = GNUNET_SCHEDULER_add_delayed (pg->feedback_frequency,
  806. &set_feedback_task, pg);
  807. }
  808. static void
  809. set_pref_task (void *cls,
  810. const struct GNUNET_SCHEDULER_TaskContext *tc)
  811. {
  812. struct PreferenceGenerator *pg = cls;
  813. struct TestPeer *p;
  814. double pref_value;
  815. pg->set_task = NULL;
  816. if (NULL == (p = find_peer_by_id (pg->peer)))
  817. {
  818. GNUNET_break (0);
  819. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  820. "Setting preference for unknown peer %u\n", pg->peer);
  821. return;
  822. }
  823. pref_value = get_preference (pg);
  824. switch (pg->kind) {
  825. case GNUNET_ATS_PREFERENCE_BANDWIDTH:
  826. pg->pref_bw_old = pref_value;
  827. break;
  828. case GNUNET_ATS_PREFERENCE_LATENCY:
  829. pg->pref_latency_old = pref_value;
  830. break;
  831. default:
  832. break;
  833. }
  834. p->pref_abs[pg->kind] = pref_value;
  835. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  836. "Setting preference for peer [%u] for client %p pref %s to %f\n",
  837. pg->peer, NULL + (pg->client_id),
  838. GNUNET_ATS_print_preference_type (pg->kind), pref_value);
  839. if (GNUNET_YES == opt_disable_normalization)
  840. {
  841. p->pref_abs[pg->kind] = pref_value;
  842. p->pref_norm[pg->kind] = pref_value;
  843. sh->sf->s_pref (sh->sf->cls, &p->peer_id, pg->kind, pref_value);
  844. }
  845. else
  846. update_preference (NULL + (pg->client_id),
  847. &p->peer_id,
  848. pg->kind,
  849. pref_value);
  850. pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
  851. &set_pref_task,
  852. pg);
  853. }
  854. static struct PreferenceGenerator *
  855. find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
  856. {
  857. struct PreferenceGenerator *cur;
  858. for (cur = pref_gen_head; NULL != cur; cur = cur->next)
  859. if (cur->peer == peer)
  860. {
  861. if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
  862. return cur;
  863. }
  864. return NULL;
  865. }
  866. void
  867. GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
  868. {
  869. GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
  870. if (NULL != pg->feedback_task)
  871. {
  872. GNUNET_SCHEDULER_cancel (pg->feedback_task);
  873. pg->feedback_task = NULL;
  874. }
  875. if (NULL != pg->set_task)
  876. {
  877. GNUNET_SCHEDULER_cancel (pg->set_task);
  878. pg->set_task = NULL;
  879. }
  880. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  881. "Removing old up preference generator peer [%u] `%s'\n",
  882. pg->peer, GNUNET_ATS_print_preference_type(pg->kind));
  883. GNUNET_free (pg);
  884. }
  885. static struct TestAddress*
  886. find_active_address (struct TestPeer *p)
  887. {
  888. struct TestAddress *cur;
  889. for (cur = p->addr_head; NULL != cur; cur = cur->next)
  890. if (GNUNET_YES == cur->ats_addr->active)
  891. return cur;
  892. return NULL;
  893. }
  894. /**
  895. * Generate between the source master and the partner and set property with a
  896. * value depending on the generator.
  897. *
  898. * @param peer source
  899. * @param address_id partner
  900. * @param client_id the client
  901. * @param type type of generator
  902. * @param base_value base value
  903. * @param value_rate maximum value
  904. * @param period duration of a period of generation (~ 1/frequency)
  905. * @param frequency how long to generate property
  906. * @param kind ATS preference to generate
  907. * @param feedback_frequency how often to give feedback
  908. * @return the preference generator
  909. */
  910. struct PreferenceGenerator *
  911. GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
  912. unsigned int address_id,
  913. unsigned int client_id,
  914. enum GeneratorType type,
  915. long int base_value,
  916. long int value_rate,
  917. struct GNUNET_TIME_Relative period,
  918. struct GNUNET_TIME_Relative frequency,
  919. enum GNUNET_ATS_PreferenceKind kind,
  920. struct GNUNET_TIME_Relative feedback_frequency)
  921. {
  922. struct PreferenceGenerator *pg;
  923. struct TestPeer *p;
  924. if (NULL == (p = find_peer_by_id (peer)))
  925. {
  926. GNUNET_break (0);
  927. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  928. "Starting preference for unknown peer %u\n", peer);
  929. return NULL;
  930. }
  931. pg = GNUNET_new (struct PreferenceGenerator);
  932. GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
  933. pg->type = type;
  934. pg->peer = peer;
  935. pg->client_id = client_id;
  936. pg->kind = kind;
  937. pg->base_value = base_value;
  938. pg->max_value = value_rate;
  939. pg->duration_period = period;
  940. pg->frequency = frequency;
  941. pg->time_start = GNUNET_TIME_absolute_get();
  942. pg->feedback_frequency = feedback_frequency;
  943. switch (type) {
  944. case GNUNET_ATS_TEST_TG_CONSTANT:
  945. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  946. "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
  947. print_generator_type (type), pg->peer,
  948. GNUNET_ATS_print_preference_type(kind),
  949. base_value);
  950. break;
  951. case GNUNET_ATS_TEST_TG_LINEAR:
  952. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  953. "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
  954. print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
  955. base_value, value_rate);
  956. break;
  957. case GNUNET_ATS_TEST_TG_SINUS:
  958. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  959. "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
  960. print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
  961. base_value, value_rate);
  962. break;
  963. case GNUNET_ATS_TEST_TG_RANDOM:
  964. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  965. "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
  966. print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
  967. base_value, value_rate);
  968. break;
  969. default:
  970. break;
  971. }
  972. pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
  973. if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != feedback_frequency.rel_value_us)
  974. {
  975. struct TestAddress * addr = find_active_address(p);
  976. pg->last_assigned_bw_in = p->assigned_bw_in;
  977. pg->last_assigned_bw_out = p->assigned_bw_out;
  978. pg->feedback_bw_in_acc = 0;
  979. pg->feedback_bw_out_acc = 0;
  980. pg->last_delay_value = addr->prop_norm[GNUNET_ATS_QUALITY_NET_DELAY];
  981. pg->feedback_delay_acc = 0;
  982. pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
  983. pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
  984. pg->feedback_last = GNUNET_TIME_absolute_get();
  985. pg->feedback_task = GNUNET_SCHEDULER_add_delayed (feedback_frequency,
  986. &set_feedback_task, pg);
  987. }
  988. return pg;
  989. }
  990. /**
  991. * Stop all preferences generators
  992. */
  993. void
  994. GNUNET_ATS_solver_generate_preferences_stop_all ()
  995. {
  996. struct PreferenceGenerator *cur;
  997. struct PreferenceGenerator *next;
  998. next = pref_gen_head;
  999. for (cur = next; NULL != cur; cur = next)
  1000. {
  1001. next = cur->next;
  1002. GNUNET_ATS_solver_generate_preferences_stop(cur);
  1003. }
  1004. }
  1005. /**
  1006. * Experiments
  1007. */
  1008. static const char *
  1009. print_op (enum OperationType op)
  1010. {
  1011. switch (op) {
  1012. case SOLVER_OP_ADD_ADDRESS:
  1013. return "ADD_ADDRESS";
  1014. case SOLVER_OP_DEL_ADDRESS:
  1015. return "DEL_ADDRESS";
  1016. case SOLVER_OP_START_SET_PREFERENCE:
  1017. return "START_SET_PREFERENCE";
  1018. case SOLVER_OP_STOP_SET_PREFERENCE:
  1019. return "STOP_STOP_PREFERENCE";
  1020. case SOLVER_OP_START_SET_PROPERTY:
  1021. return "START_SET_PROPERTY";
  1022. case SOLVER_OP_STOP_SET_PROPERTY:
  1023. return "STOP_SET_PROPERTY";
  1024. case SOLVER_OP_START_REQUEST:
  1025. return "START_REQUEST";
  1026. case SOLVER_OP_STOP_REQUEST:
  1027. return "STOP_REQUEST";
  1028. default:
  1029. break;
  1030. }
  1031. return "";
  1032. }
  1033. static struct Experiment *
  1034. create_experiment ()
  1035. {
  1036. struct Experiment *e;
  1037. e = GNUNET_new (struct Experiment);
  1038. e->name = NULL;
  1039. e->start = NULL;
  1040. e->total_duration = GNUNET_TIME_UNIT_ZERO;
  1041. return e;
  1042. }
  1043. static void
  1044. free_experiment (struct Experiment *e)
  1045. {
  1046. struct Episode *cur;
  1047. struct Episode *next;
  1048. struct GNUNET_ATS_TEST_Operation *cur_o;
  1049. struct GNUNET_ATS_TEST_Operation *next_o;
  1050. next = e->start;
  1051. for (cur = next; NULL != cur; cur = next)
  1052. {
  1053. next = cur->next;
  1054. next_o = cur->head;
  1055. for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
  1056. {
  1057. next_o = cur_o->next;
  1058. GNUNET_free_non_null (cur_o->address);
  1059. GNUNET_free_non_null (cur_o->plugin);
  1060. GNUNET_free (cur_o);
  1061. }
  1062. GNUNET_free (cur);
  1063. }
  1064. GNUNET_free_non_null (e->name);
  1065. GNUNET_free_non_null (e->log_prefix);
  1066. GNUNET_free_non_null (e->log_output_dir);
  1067. GNUNET_free_non_null (e->cfg_file);
  1068. GNUNET_free (e);
  1069. }
  1070. static int
  1071. load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
  1072. struct Episode *e,
  1073. int op_counter,
  1074. char *sec_name,
  1075. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1076. {
  1077. char *op_name;
  1078. char *op_network;
  1079. /* peer pid */
  1080. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1081. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1082. sec_name, op_name, &o->peer_id))
  1083. {
  1084. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1085. op_counter, "ADD_ADDRESS", op_name);
  1086. GNUNET_free (op_name);
  1087. return GNUNET_SYSERR;
  1088. }
  1089. GNUNET_free (op_name);
  1090. /* address pid */
  1091. GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
  1092. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1093. sec_name, op_name, &o->address_id))
  1094. {
  1095. fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
  1096. op_counter, "ADD_ADDRESS", op_name);
  1097. GNUNET_free (op_name);
  1098. return GNUNET_SYSERR;
  1099. }
  1100. GNUNET_free (op_name);
  1101. /* plugin */
  1102. GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
  1103. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1104. sec_name, op_name, &o->plugin))
  1105. {
  1106. fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
  1107. op_counter, "ADD_ADDRESS", op_name);
  1108. GNUNET_free (op_name);
  1109. return GNUNET_SYSERR;
  1110. }
  1111. GNUNET_free (op_name);
  1112. /* address */
  1113. GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
  1114. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1115. sec_name, op_name, &o->address))
  1116. {
  1117. fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
  1118. op_counter, "ADD_ADDRESS", op_name);
  1119. GNUNET_free (op_name);
  1120. return GNUNET_SYSERR;
  1121. }
  1122. GNUNET_free (op_name);
  1123. /* session */
  1124. GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
  1125. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1126. sec_name, op_name, &o->address_session))
  1127. {
  1128. fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
  1129. op_counter, "ADD_ADDRESS", op_name);
  1130. GNUNET_free (op_name);
  1131. return GNUNET_SYSERR;
  1132. }
  1133. GNUNET_free (op_name);
  1134. /* network */
  1135. GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
  1136. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1137. sec_name, op_name, &op_network))
  1138. {
  1139. fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
  1140. op_counter, "ADD_ADDRESS", op_name);
  1141. GNUNET_free (op_name);
  1142. return GNUNET_SYSERR;
  1143. }
  1144. else
  1145. {
  1146. GNUNET_STRINGS_utf8_toupper (op_network,op_network);
  1147. if (0 == strcmp(op_network, "UNSPECIFIED"))
  1148. {
  1149. o->address_network = GNUNET_ATS_NET_UNSPECIFIED;
  1150. }
  1151. else if (0 == strcmp(op_network, "LOOPBACK"))
  1152. {
  1153. o->address_network = GNUNET_ATS_NET_LOOPBACK;
  1154. }
  1155. else if (0 == strcmp(op_network, "LAN"))
  1156. {
  1157. o->address_network = GNUNET_ATS_NET_LAN;
  1158. }
  1159. else if (0 == strcmp(op_network, "WAN"))
  1160. {
  1161. o->address_network = GNUNET_ATS_NET_WAN;
  1162. }
  1163. else if (0 == strcmp(op_network, "WLAN"))
  1164. {
  1165. o->address_network = GNUNET_ATS_NET_WLAN;
  1166. }
  1167. else if (0 == strcmp(op_network, "BT"))
  1168. {
  1169. o->address_network = GNUNET_ATS_NET_BT;
  1170. }
  1171. else
  1172. {
  1173. fprintf (stderr, "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
  1174. op_counter, "ADD_ADDRESS", op_name, op_network);
  1175. GNUNET_free (op_network);
  1176. GNUNET_free (op_name);
  1177. return GNUNET_SYSERR;
  1178. }
  1179. }
  1180. GNUNET_free (op_network);
  1181. GNUNET_free (op_name);
  1182. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1183. "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
  1184. "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
  1185. return GNUNET_OK;
  1186. }
  1187. static int
  1188. load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
  1189. struct Episode *e,
  1190. int op_counter,
  1191. char *sec_name,
  1192. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1193. {
  1194. char *op_name;
  1195. //char *op_network;
  1196. /* peer pid */
  1197. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1198. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1199. sec_name, op_name, &o->peer_id))
  1200. {
  1201. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1202. op_counter, "DEL_ADDRESS", op_name);
  1203. GNUNET_free (op_name);
  1204. return GNUNET_SYSERR;
  1205. }
  1206. GNUNET_free (op_name);
  1207. /* address pid */
  1208. GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
  1209. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1210. sec_name, op_name, &o->address_id))
  1211. {
  1212. fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
  1213. op_counter, "DEL_ADDRESS", op_name);
  1214. GNUNET_free (op_name);
  1215. return GNUNET_SYSERR;
  1216. }
  1217. GNUNET_free (op_name);
  1218. #if 0
  1219. /* plugin */
  1220. GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
  1221. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1222. sec_name, op_name, &o->plugin))
  1223. {
  1224. fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
  1225. op_counter, "DEL_ADDRESS", op_name);
  1226. GNUNET_free (op_name);
  1227. return GNUNET_SYSERR;
  1228. }
  1229. GNUNET_free (op_name);
  1230. /* address */
  1231. GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
  1232. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1233. sec_name, op_name, &o->address))
  1234. {
  1235. fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
  1236. op_counter, "DEL_ADDRESS", op_name);
  1237. GNUNET_free (op_name);
  1238. return GNUNET_SYSERR;
  1239. }
  1240. GNUNET_free (op_name);
  1241. /* session */
  1242. GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
  1243. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1244. sec_name, op_name, &o->address_session))
  1245. {
  1246. fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
  1247. op_counter, "DEL_ADDRESS", op_name);
  1248. GNUNET_free (op_name);
  1249. return GNUNET_SYSERR;
  1250. }
  1251. GNUNET_free (op_name);
  1252. #endif
  1253. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1254. "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
  1255. "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
  1256. return GNUNET_OK;
  1257. }
  1258. static enum GNUNET_ATS_Property
  1259. parse_preference_string (const char * str)
  1260. {
  1261. int c = 0;
  1262. char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
  1263. for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
  1264. if (0 == strcmp(str, props[c]))
  1265. return c;
  1266. return 0;
  1267. }
  1268. static int
  1269. load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
  1270. struct Episode *e,
  1271. int op_counter,
  1272. char *sec_name,
  1273. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1274. {
  1275. char *op_name;
  1276. char *type;
  1277. char *pref;
  1278. /* peer pid */
  1279. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1280. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1281. sec_name, op_name, &o->peer_id))
  1282. {
  1283. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1284. op_counter, "START_SET_PREFERENCE", op_name);
  1285. GNUNET_free (op_name);
  1286. return GNUNET_SYSERR;
  1287. }
  1288. GNUNET_free (op_name);
  1289. /* address pid */
  1290. GNUNET_asprintf(&op_name, "op-%u-client-id", op_counter);
  1291. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1292. sec_name, op_name, &o->client_id))
  1293. {
  1294. fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
  1295. op_counter, "START_SET_PREFERENCE", op_name);
  1296. GNUNET_free (op_name);
  1297. return GNUNET_SYSERR;
  1298. }
  1299. GNUNET_free (op_name);
  1300. /* generator */
  1301. GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
  1302. if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
  1303. sec_name, op_name, &type)) )
  1304. {
  1305. fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
  1306. op_counter, "START_SET_PREFERENCE", op_name);
  1307. GNUNET_free (op_name);
  1308. return GNUNET_SYSERR;
  1309. }
  1310. /* Load arguments for set_rate, start_send, set_preference */
  1311. if (0 == strcmp (type, "constant"))
  1312. {
  1313. o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
  1314. }
  1315. else if (0 == strcmp (type, "linear"))
  1316. {
  1317. o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
  1318. }
  1319. else if (0 == strcmp (type, "sinus"))
  1320. {
  1321. o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
  1322. }
  1323. else if (0 == strcmp (type, "random"))
  1324. {
  1325. o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
  1326. }
  1327. else
  1328. {
  1329. fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
  1330. op_counter, op_name, e->id);
  1331. GNUNET_free (type);
  1332. GNUNET_free (op_name);
  1333. return GNUNET_SYSERR;
  1334. }
  1335. GNUNET_free (type);
  1336. GNUNET_free (op_name);
  1337. /* Get base rate */
  1338. GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
  1339. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1340. sec_name, op_name, &o->base_rate))
  1341. {
  1342. fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
  1343. op_counter, op_name, e->id);
  1344. GNUNET_free (op_name);
  1345. return GNUNET_SYSERR;
  1346. }
  1347. GNUNET_free (op_name);
  1348. /* Get max rate */
  1349. GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
  1350. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1351. sec_name, op_name, &o->max_rate))
  1352. {
  1353. if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
  1354. (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
  1355. (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
  1356. {
  1357. fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
  1358. op_counter, op_name, e->id);
  1359. GNUNET_free (op_name);
  1360. return GNUNET_SYSERR;
  1361. }
  1362. }
  1363. GNUNET_free (op_name);
  1364. /* Get period */
  1365. GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
  1366. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
  1367. sec_name, op_name, &o->period))
  1368. {
  1369. o->period = e->duration;
  1370. }
  1371. GNUNET_free (op_name);
  1372. /* Get frequency */
  1373. GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
  1374. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
  1375. sec_name, op_name, &o->frequency))
  1376. {
  1377. fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
  1378. op_counter, op_name, e->id);
  1379. GNUNET_free (op_name);
  1380. return GNUNET_SYSERR;
  1381. }
  1382. GNUNET_free (op_name);
  1383. /* Get preference */
  1384. GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
  1385. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1386. sec_name, op_name, &pref))
  1387. {
  1388. fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
  1389. op_counter, op_name, e->id);
  1390. GNUNET_free (op_name);
  1391. return GNUNET_SYSERR;
  1392. }
  1393. if (0 == (o->pref_type = parse_preference_string(pref)))
  1394. {
  1395. fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
  1396. op_counter, op_name, e->id);
  1397. GNUNET_free (op_name);
  1398. GNUNET_free (pref);
  1399. return GNUNET_SYSERR;
  1400. }
  1401. GNUNET_free (pref);
  1402. GNUNET_free (op_name);
  1403. /* Get feedback delay */
  1404. GNUNET_asprintf(&op_name, "op-%u-feedback_delay", op_counter);
  1405. if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg,
  1406. sec_name, op_name, &o->feedback_delay))
  1407. {
  1408. fprintf (stderr, "Using feedback delay %llu in operation %u `%s' in episode %u\n",
  1409. (long long unsigned int) o->feedback_delay.rel_value_us,
  1410. op_counter, op_name, e->id);
  1411. }
  1412. else
  1413. o->feedback_delay = GNUNET_TIME_UNIT_FOREVER_REL;
  1414. GNUNET_free (op_name);
  1415. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1416. "Found operation %s: [%llu:%llu]: %s = %llu\n",
  1417. "START_SET_PREFERENCE", o->peer_id, o->address_id,
  1418. GNUNET_ATS_print_preference_type(o->pref_type), o->base_rate);
  1419. return GNUNET_OK;
  1420. }
  1421. static int
  1422. load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
  1423. struct Episode *e,
  1424. int op_counter,
  1425. char *sec_name,
  1426. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1427. {
  1428. char *op_name;
  1429. char *pref;
  1430. /* peer pid */
  1431. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1432. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1433. sec_name, op_name, &o->peer_id))
  1434. {
  1435. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1436. op_counter, "STOP_SET_PREFERENCE", op_name);
  1437. GNUNET_free (op_name);
  1438. return GNUNET_SYSERR;
  1439. }
  1440. GNUNET_free (op_name);
  1441. /* address pid */
  1442. GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
  1443. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1444. sec_name, op_name, &o->address_id))
  1445. {
  1446. fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
  1447. op_counter, "STOP_SET_PREFERENCE", op_name);
  1448. GNUNET_free (op_name);
  1449. return GNUNET_SYSERR;
  1450. }
  1451. GNUNET_free (op_name);
  1452. /* Get preference */
  1453. GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
  1454. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1455. sec_name, op_name, &pref))
  1456. {
  1457. fprintf (stderr, "Missing preference in operation %u `%s' in episode `%s'\n",
  1458. op_counter, "STOP_SET_PREFERENCE", op_name);
  1459. GNUNET_free (op_name);
  1460. return GNUNET_SYSERR;
  1461. }
  1462. if (0 == (o->pref_type = parse_preference_string(pref)))
  1463. {
  1464. fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
  1465. op_counter, op_name, e->id);
  1466. GNUNET_free (op_name);
  1467. GNUNET_free (pref);
  1468. return GNUNET_SYSERR;
  1469. }
  1470. GNUNET_free (pref);
  1471. GNUNET_free (op_name);
  1472. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1473. "Found operation %s: [%llu:%llu]: %s\n",
  1474. "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
  1475. GNUNET_ATS_print_preference_type(o->pref_type));
  1476. return GNUNET_OK;
  1477. }
  1478. static enum GNUNET_ATS_Property
  1479. parse_property_string (const char *str)
  1480. {
  1481. enum GNUNET_ATS_Property c;
  1482. for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
  1483. if (0 == strcmp(str,
  1484. GNUNET_ATS_print_property_type (c)))
  1485. return c;
  1486. return 0;
  1487. }
  1488. static int
  1489. load_op_start_set_property(struct GNUNET_ATS_TEST_Operation *o,
  1490. struct Episode *e,
  1491. int op_counter,
  1492. char *sec_name,
  1493. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1494. {
  1495. char *op_name;
  1496. char *type;
  1497. char *prop;
  1498. /* peer pid */
  1499. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1500. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1501. sec_name, op_name, &o->peer_id))
  1502. {
  1503. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1504. op_counter, "START_SET_PROPERTY", op_name);
  1505. GNUNET_free (op_name);
  1506. return GNUNET_SYSERR;
  1507. }
  1508. GNUNET_free (op_name);
  1509. /* address pid */
  1510. GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
  1511. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1512. sec_name, op_name, &o->address_id))
  1513. {
  1514. fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
  1515. op_counter, "START_SET_PROPERTY", op_name);
  1516. GNUNET_free (op_name);
  1517. return GNUNET_SYSERR;
  1518. }
  1519. GNUNET_free (op_name);
  1520. /* generator */
  1521. GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
  1522. if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
  1523. sec_name, op_name, &type)) )
  1524. {
  1525. fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
  1526. op_counter, "START_SET_PROPERTY", op_name);
  1527. GNUNET_free (op_name);
  1528. return GNUNET_SYSERR;
  1529. }
  1530. /* Load arguments for set_rate, start_send, set_preference */
  1531. if (0 == strcmp (type, "constant"))
  1532. {
  1533. o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
  1534. }
  1535. else if (0 == strcmp (type, "linear"))
  1536. {
  1537. o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
  1538. }
  1539. else if (0 == strcmp (type, "sinus"))
  1540. {
  1541. o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
  1542. }
  1543. else if (0 == strcmp (type, "random"))
  1544. {
  1545. o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
  1546. }
  1547. else
  1548. {
  1549. fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
  1550. op_counter, op_name, e->id);
  1551. GNUNET_free (type);
  1552. GNUNET_free (op_name);
  1553. return GNUNET_SYSERR;
  1554. }
  1555. GNUNET_free (type);
  1556. GNUNET_free (op_name);
  1557. /* Get base rate */
  1558. GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
  1559. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1560. sec_name, op_name, &o->base_rate))
  1561. {
  1562. fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
  1563. op_counter, op_name, e->id);
  1564. GNUNET_free (op_name);
  1565. return GNUNET_SYSERR;
  1566. }
  1567. GNUNET_free (op_name);
  1568. /* Get max rate */
  1569. GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
  1570. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1571. sec_name, op_name, &o->max_rate))
  1572. {
  1573. if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
  1574. (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
  1575. (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
  1576. {
  1577. fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
  1578. op_counter, op_name, e->id);
  1579. GNUNET_free (op_name);
  1580. return GNUNET_SYSERR;
  1581. }
  1582. }
  1583. GNUNET_free (op_name);
  1584. /* Get period */
  1585. GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
  1586. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
  1587. sec_name, op_name, &o->period))
  1588. {
  1589. o->period = e->duration;
  1590. }
  1591. GNUNET_free (op_name);
  1592. /* Get frequency */
  1593. GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
  1594. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
  1595. sec_name, op_name, &o->frequency))
  1596. {
  1597. fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
  1598. op_counter, op_name, e->id);
  1599. GNUNET_free (op_name);
  1600. return GNUNET_SYSERR;
  1601. }
  1602. GNUNET_free (op_name);
  1603. /* Get preference */
  1604. GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
  1605. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1606. sec_name, op_name, &prop))
  1607. {
  1608. fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
  1609. op_counter, op_name, e->id);
  1610. GNUNET_free (op_name);
  1611. GNUNET_free_non_null (prop);
  1612. return GNUNET_SYSERR;
  1613. }
  1614. if (0 == (o->prop_type = parse_property_string(prop)))
  1615. {
  1616. fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
  1617. op_counter, op_name, e->id);
  1618. GNUNET_free (op_name);
  1619. GNUNET_free (prop);
  1620. return GNUNET_SYSERR;
  1621. }
  1622. GNUNET_free (prop);
  1623. GNUNET_free (op_name);
  1624. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1625. "Found operation %s: [%llu:%llu] %s = %llu\n",
  1626. "START_SET_PROPERTY", o->peer_id, o->address_id,
  1627. GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
  1628. return GNUNET_OK;
  1629. }
  1630. static int
  1631. load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
  1632. struct Episode *e,
  1633. int op_counter,
  1634. char *sec_name,
  1635. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1636. {
  1637. char *op_name;
  1638. char *pref;
  1639. /* peer pid */
  1640. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1641. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1642. sec_name, op_name, &o->peer_id))
  1643. {
  1644. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1645. op_counter, "STOP_SET_PROPERTY", op_name);
  1646. GNUNET_free (op_name);
  1647. return GNUNET_SYSERR;
  1648. }
  1649. GNUNET_free (op_name);
  1650. /* address pid */
  1651. GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
  1652. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1653. sec_name, op_name, &o->address_id))
  1654. {
  1655. fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
  1656. op_counter, "STOP_SET_PROPERTY", op_name);
  1657. GNUNET_free (op_name);
  1658. return GNUNET_SYSERR;
  1659. }
  1660. GNUNET_free (op_name);
  1661. /* Get property */
  1662. GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
  1663. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  1664. sec_name, op_name, &pref))
  1665. {
  1666. fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
  1667. op_counter, "STOP_SET_PROPERTY", op_name);
  1668. GNUNET_free (op_name);
  1669. GNUNET_free_non_null (pref);
  1670. return GNUNET_SYSERR;
  1671. }
  1672. if (0 == (o->prop_type = parse_property_string(pref)))
  1673. {
  1674. fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
  1675. op_counter, op_name, e->id);
  1676. GNUNET_free (op_name);
  1677. GNUNET_free_non_null (pref);
  1678. return GNUNET_SYSERR;
  1679. }
  1680. GNUNET_free (pref);
  1681. GNUNET_free (op_name);
  1682. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1683. "Found operation %s: [%llu:%llu] %s\n",
  1684. "STOP_SET_PROPERTY", o->peer_id, o->address_id,
  1685. GNUNET_ATS_print_property_type (o->prop_type));
  1686. return GNUNET_OK;
  1687. }
  1688. static int
  1689. load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
  1690. struct Episode *e,
  1691. int op_counter,
  1692. char *sec_name,
  1693. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1694. {
  1695. char *op_name;
  1696. /* peer pid */
  1697. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1698. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1699. sec_name, op_name, &o->peer_id))
  1700. {
  1701. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1702. op_counter, "START_REQUEST", op_name);
  1703. GNUNET_free (op_name);
  1704. return GNUNET_SYSERR;
  1705. }
  1706. GNUNET_free (op_name);
  1707. return GNUNET_OK;
  1708. }
  1709. static int
  1710. load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
  1711. struct Episode *e,
  1712. int op_counter,
  1713. char *sec_name,
  1714. const struct GNUNET_CONFIGURATION_Handle *cfg)
  1715. {
  1716. char *op_name;
  1717. /* peer pid */
  1718. GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
  1719. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  1720. sec_name, op_name, &o->peer_id))
  1721. {
  1722. fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
  1723. op_counter, "STOP_REQUEST", op_name);
  1724. GNUNET_free (op_name);
  1725. return GNUNET_SYSERR;
  1726. }
  1727. GNUNET_free (op_name);
  1728. return GNUNET_OK;
  1729. }
  1730. static int
  1731. load_episode (struct Experiment *e, struct Episode *cur,
  1732. struct GNUNET_CONFIGURATION_Handle *cfg)
  1733. {
  1734. struct GNUNET_ATS_TEST_Operation *o;
  1735. char *sec_name;
  1736. char *op_name;
  1737. char *op;
  1738. int op_counter = 0;
  1739. int res;
  1740. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n",cur->id);
  1741. GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
  1742. while (1)
  1743. {
  1744. /* Load operation */
  1745. GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
  1746. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
  1747. sec_name, op_name, &op))
  1748. {
  1749. GNUNET_free (op_name);
  1750. break;
  1751. }
  1752. o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
  1753. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
  1754. cur->id, op_name);
  1755. /* operations = set_rate, start_send, stop_send, set_preference */
  1756. if (0 == strcmp (op, "address_add"))
  1757. {
  1758. o->type = SOLVER_OP_ADD_ADDRESS;
  1759. res = load_op_add_address (o, cur,
  1760. op_counter, sec_name, cfg);
  1761. }
  1762. else if (0 == strcmp (op, "address_del"))
  1763. {
  1764. o->type = SOLVER_OP_DEL_ADDRESS;
  1765. res = load_op_del_address (o, cur,
  1766. op_counter, sec_name, cfg);
  1767. }
  1768. else if (0 == strcmp (op, "start_set_property"))
  1769. {
  1770. o->type = SOLVER_OP_START_SET_PROPERTY;
  1771. res = load_op_start_set_property (o, cur,
  1772. op_counter, sec_name, cfg);
  1773. }
  1774. else if (0 == strcmp (op, "stop_set_property"))
  1775. {
  1776. o->type = SOLVER_OP_STOP_SET_PROPERTY;
  1777. res = load_op_stop_set_property (o, cur,
  1778. op_counter, sec_name, cfg);
  1779. }
  1780. else if (0 == strcmp (op, "start_set_preference"))
  1781. {
  1782. o->type = SOLVER_OP_START_SET_PREFERENCE;
  1783. res = load_op_start_set_preference (o, cur,
  1784. op_counter, sec_name, cfg);
  1785. }
  1786. else if (0 == strcmp (op, "stop_set_preference"))
  1787. {
  1788. o->type = SOLVER_OP_STOP_SET_PREFERENCE;
  1789. res = load_op_stop_set_preference (o, cur,
  1790. op_counter, sec_name, cfg);
  1791. }
  1792. else if (0 == strcmp (op, "start_request"))
  1793. {
  1794. o->type = SOLVER_OP_START_REQUEST;
  1795. res = load_op_start_request (o, cur,
  1796. op_counter, sec_name, cfg);
  1797. }
  1798. else if (0 == strcmp (op, "stop_request"))
  1799. {
  1800. o->type = SOLVER_OP_STOP_REQUEST;
  1801. res = load_op_stop_request(o, cur,
  1802. op_counter, sec_name, cfg);
  1803. }
  1804. else
  1805. {
  1806. fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
  1807. op_counter, op, cur->id);
  1808. res = GNUNET_SYSERR;
  1809. }
  1810. GNUNET_free (op);
  1811. GNUNET_free (op_name);
  1812. if (GNUNET_SYSERR == res)
  1813. {
  1814. GNUNET_free (o);
  1815. GNUNET_free (sec_name);
  1816. return GNUNET_SYSERR;
  1817. }
  1818. GNUNET_CONTAINER_DLL_insert_tail (cur->head,cur->tail, o);
  1819. op_counter++;
  1820. }
  1821. GNUNET_free (sec_name);
  1822. return GNUNET_OK;
  1823. }
  1824. static int
  1825. load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
  1826. {
  1827. int e_counter = 0;
  1828. char *sec_name;
  1829. struct GNUNET_TIME_Relative e_duration;
  1830. struct Episode *cur;
  1831. struct Episode *last;
  1832. e_counter = 0;
  1833. last = NULL;
  1834. while (1)
  1835. {
  1836. GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
  1837. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
  1838. sec_name, "duration", &e_duration))
  1839. {
  1840. GNUNET_free (sec_name);
  1841. break;
  1842. }
  1843. cur = GNUNET_new (struct Episode);
  1844. cur->duration = e_duration;
  1845. cur->id = e_counter;
  1846. if (GNUNET_OK != load_episode (e, cur, cfg))
  1847. {
  1848. GNUNET_free (sec_name);
  1849. GNUNET_free (cur);
  1850. return GNUNET_SYSERR;
  1851. }
  1852. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
  1853. e_counter,
  1854. GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
  1855. /* Update experiment */
  1856. e->num_episodes ++;
  1857. e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
  1858. /* Put in linked list */
  1859. if (NULL == last)
  1860. e->start = cur;
  1861. else
  1862. last->next = cur;
  1863. GNUNET_free (sec_name);
  1864. e_counter ++;
  1865. last = cur;
  1866. }
  1867. return e_counter;
  1868. }
  1869. static void
  1870. timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
  1871. {
  1872. struct Experiment *e = cls;
  1873. e->experiment_timeout_task = NULL;
  1874. fprintf (stderr, "Experiment timeout!\n");
  1875. if (NULL != e->episode_timeout_task)
  1876. {
  1877. GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
  1878. e->episode_timeout_task = NULL;
  1879. }
  1880. e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
  1881. GNUNET_SYSERR);
  1882. }
  1883. struct ATS_Address *
  1884. create_ats_address (const struct GNUNET_PeerIdentity *peer,
  1885. const char *plugin_name,
  1886. const void *plugin_addr,
  1887. size_t plugin_addr_len,
  1888. uint32_t session_id,
  1889. uint32_t network)
  1890. {
  1891. struct ATS_Address *aa = NULL;
  1892. aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len + strlen (plugin_name) + 1);
  1893. aa->atsi = GNUNET_new (struct GNUNET_ATS_Information);
  1894. aa->atsi[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
  1895. aa->atsi[0].value = htonl (network);
  1896. aa->atsi_count = 1;
  1897. aa->peer = *peer;
  1898. aa->addr_len = plugin_addr_len;
  1899. aa->addr = &aa[1];
  1900. aa->plugin = (char *) &aa[1] + plugin_addr_len;
  1901. memcpy (&aa[1], plugin_addr, plugin_addr_len);
  1902. memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
  1903. aa->session_id = session_id;
  1904. return aa;
  1905. }
  1906. static void
  1907. enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
  1908. {
  1909. struct TestPeer *p;
  1910. struct TestAddress *a;
  1911. int c;
  1912. if (NULL == (p = find_peer_by_id (op->peer_id)))
  1913. {
  1914. p = GNUNET_new (struct TestPeer);
  1915. p->id = op->peer_id;
  1916. p->assigned_bw_in = 0;
  1917. p->assigned_bw_out = 0;
  1918. memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
  1919. for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
  1920. {
  1921. p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
  1922. p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
  1923. }
  1924. GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
  1925. }
  1926. if (NULL != (find_address_by_id (p, op->address_id)))
  1927. {
  1928. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
  1929. op->address_id, op->peer_id);
  1930. return;
  1931. }
  1932. a = GNUNET_new (struct TestAddress);
  1933. a->aid = op->address_id;
  1934. a->network = op->address_network;
  1935. a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
  1936. strlen (op->address) + 1, op->address_session, op->address_network);
  1937. memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
  1938. GNUNET_CONTAINER_DLL_insert_tail (p->addr_head, p->addr_tail, a);
  1939. for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
  1940. a->prop_norm[c] = DEFAULT_REL_QUALITY;
  1941. GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
  1942. GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
  1943. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding address %u for peer %u in network `%s'\n",
  1944. op->address_id, op->peer_id, GNUNET_ATS_print_network_type(a->network));
  1945. sh->sf->s_add (sh->sf->cls, a->ats_addr, op->address_network);
  1946. }
  1947. static void
  1948. enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
  1949. {
  1950. struct TestPeer *p;
  1951. struct TestAddress *a;
  1952. struct PropertyGenerator *pg;
  1953. if (NULL == (p = find_peer_by_id (op->peer_id)))
  1954. {
  1955. GNUNET_break (0);
  1956. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1957. "Deleting address for unknown peer %u\n", op->peer_id);
  1958. return;
  1959. }
  1960. if (NULL == (a =find_address_by_id (p, op->address_id)))
  1961. {
  1962. GNUNET_break (0);
  1963. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1964. "Deleting address for unknown peer %u\n", op->peer_id);
  1965. return;
  1966. }
  1967. while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
  1968. {
  1969. GNUNET_ATS_solver_generate_property_stop (pg);
  1970. }
  1971. GNUNET_assert (GNUNET_YES ==
  1972. GNUNET_CONTAINER_multipeermap_remove (sh->addresses,
  1973. &p->peer_id,
  1974. a->ats_addr));
  1975. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1976. "Removing address %u for peer %u\n",
  1977. op->address_id,
  1978. op->peer_id);
  1979. sh->sf->s_del (sh->sf->cls, a->ats_addr);
  1980. if (NULL != l)
  1981. {
  1982. GNUNET_ATS_solver_logging_now (l);
  1983. }
  1984. GNUNET_CONTAINER_DLL_remove(p->addr_head, p->addr_tail, a);
  1985. GNUNET_free_non_null(a->ats_addr->atsi);
  1986. GNUNET_free (a->ats_addr);
  1987. GNUNET_free (a);
  1988. }
  1989. static void
  1990. enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
  1991. {
  1992. struct PropertyGenerator *pg;
  1993. struct TestPeer *p;
  1994. struct TestAddress *a;
  1995. if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
  1996. {
  1997. GNUNET_ATS_solver_generate_property_stop (pg);
  1998. GNUNET_free (pg);
  1999. }
  2000. if (NULL == (p = find_peer_by_id (op->peer_id)))
  2001. {
  2002. GNUNET_break (0);
  2003. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2004. "Starting property generation for unknown peer %u\n", op->peer_id);
  2005. return;
  2006. }
  2007. if (NULL == (a = find_address_by_id (p, op->address_id)))
  2008. {
  2009. GNUNET_break (0);
  2010. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2011. "Setting property for unknown address %u\n", op->peer_id);
  2012. return;
  2013. }
  2014. GNUNET_ATS_solver_generate_property_start (op->peer_id,
  2015. op->address_id,
  2016. p, a,
  2017. op->gen_type,
  2018. op->base_rate,
  2019. op->max_rate,
  2020. op->period,
  2021. op->frequency,
  2022. op->prop_type);
  2023. }
  2024. static void
  2025. enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
  2026. {
  2027. struct PropertyGenerator *pg = find_prop_gen(op->peer_id, op->address_id,
  2028. op->prop_type);
  2029. if (NULL != pg)
  2030. {
  2031. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  2032. "Stopping preference generation for peer %u address %u\n", op->peer_id,
  2033. op->address_id);
  2034. GNUNET_ATS_solver_generate_property_stop (pg);
  2035. }
  2036. else
  2037. {
  2038. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2039. "Cannot find preference generator for peer %u address %u\n",
  2040. op->peer_id, op->address_id);
  2041. GNUNET_break (0);
  2042. }
  2043. }
  2044. static void
  2045. enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
  2046. {
  2047. struct PreferenceGenerator *pg;
  2048. if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
  2049. {
  2050. GNUNET_ATS_solver_generate_preferences_stop (pg);
  2051. GNUNET_free (pg);
  2052. }
  2053. if (NULL == (find_peer_by_id (op->peer_id)))
  2054. {
  2055. GNUNET_break (0);
  2056. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2057. "Starting preference generation for unknown peer %u\n", op->peer_id);
  2058. return;
  2059. }
  2060. GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
  2061. op->address_id,
  2062. op->client_id,
  2063. op->gen_type,
  2064. op->base_rate,
  2065. op->max_rate,
  2066. op->period,
  2067. op->frequency,
  2068. op->pref_type,
  2069. op->frequency);
  2070. }
  2071. static void
  2072. enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
  2073. {
  2074. struct PreferenceGenerator *pg = find_pref_gen(op->peer_id,
  2075. op->pref_type);
  2076. if (NULL != pg)
  2077. {
  2078. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  2079. "Stopping property generation for peer %u address %u\n", op->peer_id,
  2080. op->address_id);
  2081. GNUNET_ATS_solver_generate_preferences_stop (pg);
  2082. }
  2083. else
  2084. {
  2085. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2086. "Cannot find preference generator for peer %u address %u\n",
  2087. op->peer_id, op->address_id);
  2088. GNUNET_break (0);
  2089. }
  2090. }
  2091. static void
  2092. enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
  2093. {
  2094. struct TestPeer *p;
  2095. if (NULL == (p = find_peer_by_id (op->peer_id)))
  2096. {
  2097. GNUNET_break (0);
  2098. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2099. "Requesting address for unknown peer %u\n", op->peer_id);
  2100. return;
  2101. }
  2102. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
  2103. op->peer_id);
  2104. p->is_requested = GNUNET_YES;
  2105. sh->sf->s_get (sh->sf->cls, &p->peer_id);
  2106. }
  2107. static void
  2108. enforce_stop_request (struct GNUNET_ATS_TEST_Operation *op)
  2109. {
  2110. struct TestPeer *p;
  2111. if (NULL == (p = find_peer_by_id (op->peer_id)))
  2112. {
  2113. GNUNET_break (0);
  2114. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2115. "Requesting address for unknown peer %u\n", op->peer_id);
  2116. return;
  2117. }
  2118. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  2119. "Stop requesting address for peer %u\n",
  2120. op->peer_id);
  2121. p->is_requested = GNUNET_NO;
  2122. p->assigned_bw_in = 0;
  2123. p->assigned_bw_out = 0;
  2124. sh->sf->s_get_stop (sh->sf->cls, &p->peer_id);
  2125. if (NULL != l)
  2126. {
  2127. GNUNET_ATS_solver_logging_now (l);
  2128. }
  2129. }
  2130. static void enforce_episode (struct Episode *ep)
  2131. {
  2132. struct GNUNET_ATS_TEST_Operation *cur;
  2133. for (cur = ep->head; NULL != cur; cur = cur->next)
  2134. {
  2135. switch (cur->type) {
  2136. case SOLVER_OP_ADD_ADDRESS:
  2137. fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
  2138. print_op (cur->type), cur->peer_id, cur->address_id);
  2139. enforce_add_address (cur);
  2140. break;
  2141. case SOLVER_OP_DEL_ADDRESS:
  2142. fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
  2143. print_op (cur->type), cur->peer_id, cur->address_id);
  2144. enforce_del_address (cur);
  2145. break;
  2146. case SOLVER_OP_START_SET_PROPERTY:
  2147. fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
  2148. print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
  2149. enforce_start_property (cur);
  2150. break;
  2151. case SOLVER_OP_STOP_SET_PROPERTY:
  2152. fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
  2153. print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
  2154. enforce_stop_property (cur);
  2155. break;
  2156. case SOLVER_OP_START_SET_PREFERENCE:
  2157. fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
  2158. print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
  2159. enforce_start_preference (cur);
  2160. break;
  2161. case SOLVER_OP_STOP_SET_PREFERENCE:
  2162. fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
  2163. print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
  2164. enforce_stop_preference (cur);
  2165. break;
  2166. case SOLVER_OP_START_REQUEST:
  2167. fprintf (stderr, "Enforcing operation: %s [%llu]\n",
  2168. print_op (cur->type), cur->peer_id);
  2169. enforce_start_request (cur);
  2170. break;
  2171. case SOLVER_OP_STOP_REQUEST:
  2172. fprintf (stderr, "Enforcing operation: %s [%llu]\n",
  2173. print_op (cur->type), cur->peer_id);
  2174. enforce_stop_request (cur);
  2175. break;
  2176. default:
  2177. break;
  2178. }
  2179. }
  2180. }
  2181. static void
  2182. timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
  2183. {
  2184. struct Experiment *e = cls;
  2185. e->episode_timeout_task = NULL;
  2186. if (NULL != e->ep_done_cb)
  2187. e->ep_done_cb (e->cur);
  2188. /* Scheduling next */
  2189. e->cur = e->cur->next;
  2190. if (NULL == e->cur)
  2191. {
  2192. /* done */
  2193. fprintf (stderr, "Last episode done!\n");
  2194. if (NULL != e->experiment_timeout_task)
  2195. {
  2196. GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
  2197. e->experiment_timeout_task = NULL;
  2198. }
  2199. e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
  2200. return;
  2201. }
  2202. fprintf (stderr, "Running episode %u with timeout %s\n",
  2203. e->cur->id,
  2204. GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
  2205. e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
  2206. &timeout_episode, e);
  2207. enforce_episode(e->cur);
  2208. }
  2209. void
  2210. GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
  2211. GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
  2212. GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
  2213. {
  2214. fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
  2215. GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
  2216. e->e_done_cb = e_done_cb;
  2217. e->ep_done_cb = ep_done_cb;
  2218. e->start_time = GNUNET_TIME_absolute_get();
  2219. /* Start total time out */
  2220. e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
  2221. &timeout_experiment, e);
  2222. /* Start */
  2223. if (NULL == e->start)
  2224. {
  2225. GNUNET_break (0);
  2226. return;
  2227. }
  2228. e->cur = e->start;
  2229. fprintf (stderr, "Running episode %u with timeout %s\n",
  2230. e->cur->id,
  2231. GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
  2232. e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
  2233. &timeout_episode, e);
  2234. enforce_episode(e->cur);
  2235. }
  2236. void
  2237. GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
  2238. {
  2239. if (NULL != e->experiment_timeout_task)
  2240. {
  2241. GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
  2242. e->experiment_timeout_task = NULL;
  2243. }
  2244. if (NULL != e->episode_timeout_task)
  2245. {
  2246. GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
  2247. e->episode_timeout_task = NULL;
  2248. }
  2249. if (NULL != e->cfg)
  2250. {
  2251. GNUNET_CONFIGURATION_destroy(e->cfg);
  2252. e->cfg = NULL;
  2253. }
  2254. free_experiment (e);
  2255. }
  2256. struct Experiment *
  2257. GNUNET_ATS_solvers_experimentation_load (char *filename)
  2258. {
  2259. struct Experiment *e;
  2260. struct GNUNET_CONFIGURATION_Handle *cfg;
  2261. e = NULL;
  2262. cfg = GNUNET_CONFIGURATION_create();
  2263. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
  2264. {
  2265. fprintf (stderr, "Failed to load `%s'\n", filename);
  2266. GNUNET_CONFIGURATION_destroy (cfg);
  2267. return NULL;
  2268. }
  2269. e = create_experiment ();
  2270. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
  2271. "name", &e->name))
  2272. {
  2273. fprintf (stderr, "Invalid %s \n", "name");
  2274. free_experiment (e);
  2275. return NULL;
  2276. }
  2277. else
  2278. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
  2279. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
  2280. "log_prefix", &e->log_prefix))
  2281. {
  2282. fprintf (stderr, "Invalid %s \n", "log_prefix");
  2283. free_experiment (e);
  2284. return NULL;
  2285. }
  2286. else
  2287. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
  2288. e->log_prefix);
  2289. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
  2290. "log_output_dir", &e->log_output_dir))
  2291. {
  2292. e->log_output_dir = NULL;
  2293. }
  2294. else
  2295. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging output directory: `%s'\n",
  2296. e->log_output_dir);
  2297. if (GNUNET_SYSERR == (e->log_append_time_stamp = GNUNET_CONFIGURATION_get_value_yesno(cfg,
  2298. "experiment", "log_append_time_stamp")))
  2299. e->log_append_time_stamp = GNUNET_YES;
  2300. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging append timestamp: `%s'\n",
  2301. (GNUNET_YES == e->log_append_time_stamp) ? "yes" : "no");
  2302. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
  2303. "cfg_file", &e->cfg_file))
  2304. {
  2305. fprintf (stderr, "Invalid %s \n", "cfg_file");
  2306. free_experiment (e);
  2307. return NULL;
  2308. }
  2309. else
  2310. {
  2311. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n", e->cfg_file);
  2312. e->cfg = GNUNET_CONFIGURATION_create();
  2313. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
  2314. {
  2315. fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
  2316. free_experiment (e);
  2317. return NULL;
  2318. }
  2319. }
  2320. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
  2321. "log_freq", &e->log_freq))
  2322. {
  2323. fprintf (stderr, "Invalid %s \n", "log_freq");
  2324. free_experiment (e);
  2325. return NULL;
  2326. }
  2327. else
  2328. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
  2329. GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
  2330. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
  2331. "max_duration", &e->max_duration))
  2332. {
  2333. fprintf (stderr, "Invalid %s", "max_duration");
  2334. free_experiment (e);
  2335. return NULL;
  2336. }
  2337. else
  2338. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
  2339. GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
  2340. if (GNUNET_SYSERR == load_episodes (e, cfg))
  2341. {
  2342. GNUNET_ATS_solvers_experimentation_stop (e);
  2343. GNUNET_CONFIGURATION_destroy (cfg);
  2344. e = NULL;
  2345. fprintf (stderr, "Failed to load experiment\n");
  2346. return NULL;
  2347. }
  2348. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loaded %u episodes with total duration %s\n",
  2349. e->num_episodes,
  2350. GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
  2351. GNUNET_CONFIGURATION_destroy (cfg);
  2352. return e;
  2353. }
  2354. /**
  2355. * Solver
  2356. */
  2357. static int
  2358. free_all_it (void *cls,
  2359. const struct GNUNET_PeerIdentity *key,
  2360. void *value)
  2361. {
  2362. struct ATS_Address *address = value;
  2363. GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (sh->env.addresses,
  2364. key, value));
  2365. GNUNET_free (address);
  2366. return GNUNET_OK;
  2367. }
  2368. void
  2369. GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
  2370. {
  2371. GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
  2372. GNUNET_NO);
  2373. GNUNET_PLUGIN_unload (sh->plugin, sh->sf);
  2374. sh->sf = NULL;
  2375. GAS_normalization_stop();
  2376. GNUNET_CONTAINER_multipeermap_iterate (sh->addresses,
  2377. &free_all_it,
  2378. NULL);
  2379. GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
  2380. GNUNET_free (sh->plugin);
  2381. GNUNET_free (sh);
  2382. }
  2383. /**
  2384. * Load quotas for networks from configuration
  2385. *
  2386. * @param cfg configuration handle
  2387. * @param out_dest where to write outbound quotas
  2388. * @param in_dest where to write inbound quotas
  2389. * @param dest_length length of inbound and outbound arrays
  2390. * @return number of networks loaded
  2391. */
  2392. unsigned int
  2393. GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
  2394. unsigned long long *out_dest,
  2395. unsigned long long *in_dest,
  2396. int dest_length)
  2397. {
  2398. char * entry_in = NULL;
  2399. char * entry_out = NULL;
  2400. char * quota_out_str;
  2401. char * quota_in_str;
  2402. int c;
  2403. int res;
  2404. for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
  2405. {
  2406. in_dest[c] = 0;
  2407. out_dest[c] = 0;
  2408. GNUNET_asprintf (&entry_out,
  2409. "%s_QUOTA_OUT",
  2410. GNUNET_ATS_print_network_type (c));
  2411. GNUNET_asprintf (&entry_in,
  2412. "%s_QUOTA_IN",
  2413. GNUNET_ATS_print_network_type (c));
  2414. /* quota out */
  2415. if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, &quota_out_str))
  2416. {
  2417. res = GNUNET_NO;
  2418. if (0 == strcmp(quota_out_str, BIG_M_STRING))
  2419. {
  2420. out_dest[c] = GNUNET_ATS_MaxBandwidth;
  2421. res = GNUNET_YES;
  2422. }
  2423. if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
  2424. res = GNUNET_YES;
  2425. if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
  2426. res = GNUNET_YES;
  2427. if (GNUNET_NO == res)
  2428. {
  2429. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2430. _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
  2431. GNUNET_ATS_print_network_type (c),
  2432. quota_out_str,
  2433. GNUNET_ATS_DefaultBandwidth);
  2434. out_dest[c] = GNUNET_ATS_DefaultBandwidth;
  2435. }
  2436. else
  2437. {
  2438. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2439. "Outbound quota configure for network `%s' is %llu\n",
  2440. GNUNET_ATS_print_network_type (c),
  2441. out_dest[c]);
  2442. }
  2443. GNUNET_free (quota_out_str);
  2444. }
  2445. else
  2446. {
  2447. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  2448. _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
  2449. GNUNET_ATS_print_network_type (c),
  2450. GNUNET_ATS_DefaultBandwidth);
  2451. out_dest[c] = GNUNET_ATS_DefaultBandwidth;
  2452. }
  2453. /* quota in */
  2454. if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, &quota_in_str))
  2455. {
  2456. res = GNUNET_NO;
  2457. if (0 == strcmp(quota_in_str, BIG_M_STRING))
  2458. {
  2459. in_dest[c] = GNUNET_ATS_MaxBandwidth;
  2460. res = GNUNET_YES;
  2461. }
  2462. if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
  2463. res = GNUNET_YES;
  2464. if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
  2465. res = GNUNET_YES;
  2466. if (GNUNET_NO == res)
  2467. {
  2468. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  2469. _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
  2470. GNUNET_ATS_print_network_type (c),
  2471. quota_in_str,
  2472. GNUNET_ATS_DefaultBandwidth);
  2473. in_dest[c] = GNUNET_ATS_DefaultBandwidth;
  2474. }
  2475. else
  2476. {
  2477. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2478. "Inbound quota configured for network `%s' is %llu\n",
  2479. GNUNET_ATS_print_network_type (c),
  2480. in_dest[c]);
  2481. }
  2482. GNUNET_free (quota_in_str);
  2483. }
  2484. else
  2485. {
  2486. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  2487. _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
  2488. GNUNET_ATS_print_network_type (c),
  2489. GNUNET_ATS_DefaultBandwidth);
  2490. out_dest[c] = GNUNET_ATS_DefaultBandwidth;
  2491. }
  2492. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  2493. "Loaded quota for network `%s' (in/out): %llu %llu\n",
  2494. GNUNET_ATS_print_network_type (c),
  2495. in_dest[c],
  2496. out_dest[c]);
  2497. GNUNET_free (entry_out);
  2498. GNUNET_free (entry_in);
  2499. }
  2500. return GNUNET_ATS_NetworkTypeCount;
  2501. }
  2502. /**
  2503. * Information callback for the solver
  2504. *
  2505. * @param cls the closure
  2506. * @param op the solver operation
  2507. * @param stat status of the solver operation
  2508. * @param add additional solver information
  2509. */
  2510. static void
  2511. solver_info_cb (void *cls,
  2512. enum GAS_Solver_Operation op,
  2513. enum GAS_Solver_Status stat,
  2514. enum GAS_Solver_Additional_Information add)
  2515. {
  2516. char *add_info;
  2517. switch (add) {
  2518. case GAS_INFO_NONE:
  2519. add_info = "GAS_INFO_NONE";
  2520. break;
  2521. case GAS_INFO_FULL:
  2522. add_info = "GAS_INFO_MLP_FULL";
  2523. break;
  2524. case GAS_INFO_UPDATED:
  2525. add_info = "GAS_INFO_MLP_UPDATED";
  2526. break;
  2527. case GAS_INFO_PROP_ALL:
  2528. add_info = "GAS_INFO_PROP_ALL";
  2529. break;
  2530. case GAS_INFO_PROP_SINGLE:
  2531. add_info = "GAS_INFO_PROP_SINGLE";
  2532. break;
  2533. default:
  2534. add_info = "INVALID";
  2535. break;
  2536. }
  2537. switch (op)
  2538. {
  2539. case GAS_OP_SOLVE_START:
  2540. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2541. "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
  2542. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
  2543. return;
  2544. case GAS_OP_SOLVE_STOP:
  2545. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2546. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
  2547. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
  2548. return;
  2549. case GAS_OP_SOLVE_SETUP_START:
  2550. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2551. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
  2552. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2553. return;
  2554. case GAS_OP_SOLVE_SETUP_STOP:
  2555. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2556. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
  2557. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2558. return;
  2559. case GAS_OP_SOLVE_MLP_LP_START:
  2560. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2561. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
  2562. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2563. return;
  2564. case GAS_OP_SOLVE_MLP_LP_STOP:
  2565. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2566. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
  2567. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2568. return;
  2569. case GAS_OP_SOLVE_MLP_MLP_START:
  2570. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2571. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
  2572. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2573. return;
  2574. case GAS_OP_SOLVE_MLP_MLP_STOP:
  2575. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2576. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
  2577. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2578. return;
  2579. case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
  2580. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2581. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
  2582. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2583. return;
  2584. case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
  2585. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  2586. "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
  2587. (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
  2588. return;
  2589. default:
  2590. break;
  2591. }
  2592. }
  2593. static void
  2594. solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
  2595. {
  2596. struct GNUNET_TIME_Relative duration;
  2597. struct TestPeer *p;
  2598. static struct PreferenceGenerator *pg;
  2599. uint32_t delta;
  2600. if ( (0 == address->assigned_bw_out) && (0 == address->assigned_bw_in) )
  2601. {
  2602. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  2603. "Solver notified to disconnect peer `%s'\n",
  2604. GNUNET_i2s (&address->peer));
  2605. }
  2606. p = find_peer_by_pid(&address->peer);
  2607. if (NULL == p)
  2608. return;
  2609. p->assigned_bw_out = address->assigned_bw_out;
  2610. p->assigned_bw_in = address->assigned_bw_in;
  2611. for (pg = pref_gen_head; NULL != pg; pg = pg->next)
  2612. {
  2613. if (pg->peer == p->id)
  2614. {
  2615. duration = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
  2616. delta = duration.rel_value_us * pg->last_assigned_bw_out;
  2617. pg->feedback_bw_out_acc += delta;
  2618. delta = duration.rel_value_us * pg->last_assigned_bw_in;
  2619. pg->feedback_bw_in_acc += delta;
  2620. pg->last_assigned_bw_in = address->assigned_bw_in;
  2621. pg->last_assigned_bw_out = address->assigned_bw_out;
  2622. pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
  2623. }
  2624. }
  2625. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  2626. "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
  2627. GNUNET_i2s (&address->peer),
  2628. address,
  2629. address->assigned_bw_out,
  2630. address->assigned_bw_in);
  2631. if (NULL != l)
  2632. GNUNET_ATS_solver_logging_now (l);
  2633. return;
  2634. }
  2635. const double *
  2636. get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
  2637. {
  2638. struct TestPeer *p;
  2639. if (GNUNET_YES == opt_disable_normalization)
  2640. {
  2641. if (NULL == (p = find_peer_by_pid (id)))
  2642. return NULL;
  2643. return p->pref_abs;
  2644. }
  2645. else
  2646. return GAS_preference_get_by_peer (NULL,
  2647. id);
  2648. }
  2649. struct SolverHandle *
  2650. GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
  2651. {
  2652. struct SolverHandle *sh;
  2653. char * solver_str;
  2654. switch (type) {
  2655. case GNUNET_ATS_SOLVER_PROPORTIONAL:
  2656. solver_str = "proportional";
  2657. break;
  2658. case GNUNET_ATS_SOLVER_MLP:
  2659. solver_str = "mlp";
  2660. break;
  2661. case GNUNET_ATS_SOLVER_RIL:
  2662. solver_str = "ril";
  2663. break;
  2664. default:
  2665. GNUNET_break (0);
  2666. return NULL;
  2667. break;
  2668. }
  2669. sh = GNUNET_new (struct SolverHandle);
  2670. GNUNET_asprintf (&sh->plugin,
  2671. "libgnunet_plugin_ats_%s",
  2672. solver_str);
  2673. sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
  2674. /* setup environment */
  2675. sh->env.cfg = e->cfg;
  2676. sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
  2677. sh->env.addresses = sh->addresses;
  2678. sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
  2679. sh->env.get_preferences = &get_preferences_cb;
  2680. sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
  2681. sh->env.info_cb = &solver_info_cb;
  2682. sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
  2683. /* start normalization */
  2684. GAS_normalization_start ();
  2685. /* load quotas */
  2686. if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
  2687. sh->env.out_quota, sh->env.in_quota, GNUNET_ATS_NetworkTypeCount))
  2688. {
  2689. GNUNET_break(0);
  2690. GNUNET_free (sh->plugin);
  2691. GNUNET_free (sh);
  2692. end_now ();
  2693. return NULL;
  2694. }
  2695. sh->sf = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
  2696. if (NULL == sh->sf)
  2697. {
  2698. fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
  2699. GNUNET_break(0);
  2700. GNUNET_free (sh->plugin);
  2701. GNUNET_free (sh);
  2702. end_now ();
  2703. return NULL;
  2704. }
  2705. return sh;
  2706. }
  2707. static void
  2708. done ()
  2709. {
  2710. struct TestPeer *cur;
  2711. struct TestPeer *next;
  2712. struct TestAddress *cur_a;
  2713. struct TestAddress *next_a;
  2714. /* Stop logging */
  2715. GNUNET_ATS_solver_logging_stop (l);
  2716. /* Stop all preference generation */
  2717. GNUNET_ATS_solver_generate_preferences_stop_all ();
  2718. /* Stop all property generation */
  2719. GNUNET_ATS_solver_generate_property_stop_all ();
  2720. if (opt_print)
  2721. {
  2722. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
  2723. GNUNET_ATS_solver_logging_eval (l);
  2724. }
  2725. if (opt_save)
  2726. {
  2727. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
  2728. GNUNET_ATS_solver_logging_write_to_disk (l, e->log_append_time_stamp,
  2729. e->log_output_dir);
  2730. }
  2731. if (NULL != l)
  2732. {
  2733. GNUNET_ATS_solver_logging_free (l);
  2734. l = NULL;
  2735. }
  2736. /* Clean up experiment */
  2737. if (NULL != e)
  2738. {
  2739. GNUNET_ATS_solvers_experimentation_stop (e);
  2740. e = NULL;
  2741. }
  2742. next = peer_head;
  2743. while (NULL != (cur = next))
  2744. {
  2745. next = cur->next;
  2746. GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
  2747. next_a = cur->addr_head;
  2748. while (NULL != (cur_a = next_a))
  2749. {
  2750. next_a = cur_a->next;
  2751. GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
  2752. GNUNET_free (cur_a);
  2753. }
  2754. GNUNET_free (cur);
  2755. }
  2756. if (NULL != sh)
  2757. {
  2758. GNUNET_ATS_solvers_solver_stop (sh);
  2759. sh = NULL;
  2760. }
  2761. /* Shutdown */
  2762. end_now();
  2763. }
  2764. static void
  2765. experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
  2766. {
  2767. if (GNUNET_OK == success)
  2768. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
  2769. GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
  2770. else
  2771. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
  2772. GNUNET_SCHEDULER_add_now (&done, NULL);
  2773. }
  2774. static void
  2775. episode_done_cb (struct Episode *ep)
  2776. {
  2777. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
  2778. }
  2779. /**
  2780. * Do shutdown
  2781. */
  2782. static void
  2783. end_now ()
  2784. {
  2785. if (NULL != e)
  2786. {
  2787. GNUNET_ATS_solvers_experimentation_stop (e);
  2788. e = NULL;
  2789. }
  2790. if (NULL != sh)
  2791. {
  2792. GNUNET_ATS_solvers_solver_stop (sh);
  2793. sh = NULL;
  2794. }
  2795. }
  2796. static void
  2797. run (void *cls, char * const *args, const char *cfgfile,
  2798. const struct GNUNET_CONFIGURATION_Handle *cfg)
  2799. {
  2800. enum GNUNET_ATS_Solvers solver;
  2801. int c;
  2802. if (NULL == opt_exp_file)
  2803. {
  2804. fprintf (stderr, "No experiment given ...\n");
  2805. res = 1;
  2806. end_now ();
  2807. return;
  2808. }
  2809. if (NULL == opt_solver)
  2810. {
  2811. fprintf (stderr, "No solver given ...\n");
  2812. res = 1;
  2813. end_now ();
  2814. return;
  2815. }
  2816. if (0 == strcmp(opt_solver, "mlp"))
  2817. {
  2818. solver = GNUNET_ATS_SOLVER_MLP;
  2819. }
  2820. else if (0 == strcmp(opt_solver, "proportional"))
  2821. {
  2822. solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
  2823. }
  2824. else if (0 == strcmp(opt_solver, "ril"))
  2825. {
  2826. solver = GNUNET_ATS_SOLVER_RIL;
  2827. }
  2828. else
  2829. {
  2830. fprintf (stderr, "No solver given ...");
  2831. res = 1;
  2832. end_now ();
  2833. return;
  2834. }
  2835. for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
  2836. default_properties[c] = DEFAULT_REL_QUALITY;
  2837. for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
  2838. default_preferences[c] = DEFAULT_REL_PREFERENCE;
  2839. /* load experiment */
  2840. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
  2841. e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
  2842. if (NULL == e)
  2843. {
  2844. fprintf (stderr, "Failed to load experiment ...\n");
  2845. res = 1;
  2846. end_now ();
  2847. return;
  2848. }
  2849. /* load solver */
  2850. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
  2851. sh = GNUNET_ATS_solvers_solver_start (solver);
  2852. if (NULL == sh)
  2853. {
  2854. fprintf (stderr, "Failed to start solver ...\n");
  2855. end_now ();
  2856. res = 1;
  2857. return;
  2858. }
  2859. /* start logging */
  2860. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
  2861. l = GNUNET_ATS_solver_logging_start (e->log_freq);
  2862. /* run experiment */
  2863. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
  2864. GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
  2865. experiment_done_cb);
  2866. /* WAIT */
  2867. }
  2868. /**
  2869. * Main function of the benchmark
  2870. *
  2871. * @param argc argument count
  2872. * @param argv argument values
  2873. */
  2874. int
  2875. main (int argc, char *argv[])
  2876. {
  2877. opt_exp_file = NULL;
  2878. opt_solver = NULL;
  2879. opt_log = GNUNET_NO;
  2880. opt_save = GNUNET_NO;
  2881. res = 0;
  2882. static struct GNUNET_GETOPT_CommandLineOption options[] =
  2883. {
  2884. { 's', "solver", NULL,
  2885. gettext_noop ("solver to use"),
  2886. 1, &GNUNET_GETOPT_set_string, &opt_solver},
  2887. { 'e', "experiment", NULL,
  2888. gettext_noop ("experiment to use"),
  2889. 1, &GNUNET_GETOPT_set_string, &opt_exp_file},
  2890. { 'V', "verbose", NULL,
  2891. gettext_noop ("be verbose"),
  2892. 0, &GNUNET_GETOPT_set_one, &opt_verbose},
  2893. { 'p', "print", NULL,
  2894. gettext_noop ("print logging"),
  2895. 0, &GNUNET_GETOPT_set_one, &opt_print},
  2896. { 'f', "file", NULL,
  2897. gettext_noop ("save logging to disk"),
  2898. 0, &GNUNET_GETOPT_set_one, &opt_save},
  2899. { 'd', "dn", NULL,
  2900. gettext_noop ("disable normalization"),
  2901. 0, &GNUNET_GETOPT_set_one, &opt_disable_normalization},
  2902. GNUNET_GETOPT_OPTION_END
  2903. };
  2904. GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
  2905. NULL, options, &run, argv[0]);
  2906. return res;
  2907. }
  2908. /* end of file ats-testing-experiment.c*/