thread_analysis.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /* Analyzes the concurrent use of charon's threads
  2. *
  3. * Copyright (C) 2008 Andreas Steffen
  4. * HSR Hochschule fuer Technik Rapperswil
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  13. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * for more details.
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #define LOGFILE "moon.daemon.log"
  20. #define LINE_LEN 2048
  21. #define THREADS 99
  22. typedef enum state_t state_t;
  23. enum state_t {
  24. STATE_IDLE = 0,
  25. STATE_INIT = 1,
  26. STATE_AUTH = 2,
  27. STATE_BUSY = 3,
  28. STATE_RETRY = 4,
  29. STATE_ERROR = 5
  30. };
  31. typedef enum print_t print_t;
  32. enum print_t {
  33. MODE_ANY = 0,
  34. MODE_ADD = 1,
  35. MODE_DEL = 2
  36. };
  37. static char *state_names[] = { "idle", "init", "auth", "busy", "retry", "error" };
  38. static int readline(FILE *fd, char *line)
  39. {
  40. while (fread(line, 1, 1, fd))
  41. {
  42. if (*line == '\n')
  43. {
  44. *line = '\0';
  45. return 1;
  46. }
  47. line++;
  48. }
  49. *line = '\0';
  50. return 0;
  51. }
  52. static void printline(state_t *state, char *timestamp)
  53. {
  54. int states[] = { 0, 0, 0, 0, 0};
  55. int th, total ;
  56. printf(" <tr>\n");
  57. printf(" <td class=\"log\">%.15s</td>", timestamp);
  58. for (th = 1; th <= THREADS; th++)
  59. {
  60. states[state[th]]++;
  61. printf("<td class=\"%s\"></td>", state_names[state[th]]);
  62. }
  63. total = states[STATE_INIT] + states[STATE_AUTH] + states[STATE_BUSY] + states[STATE_RETRY];
  64. printf("<td class=\"init\">%d</td><td class=\"auth\">%d</td><td class=\"busy\">%d</td>",
  65. states[STATE_INIT], states[STATE_AUTH], total);
  66. for (th = 10; th <= (THREADS + 2); th += 5)
  67. {
  68. printf("<td class=\"%s\"></td>", (th <= total + 2)? "busy":"idle");
  69. }
  70. printf("\n");
  71. printf(" </tr>\n");
  72. }
  73. int main(int argc, char *argv[])
  74. {
  75. char line[LINE_LEN];
  76. int section = 0;
  77. int mode = MODE_ANY;
  78. int th;
  79. FILE *fd;
  80. state_t state[THREADS + 1];
  81. /* threads 1..5 and 9 are always busy */
  82. for (th = 1; th <= THREADS; th++)
  83. {
  84. state[th] = (th <= 7 && th != 3)? STATE_BUSY : STATE_IDLE;
  85. }
  86. /* open the log file */
  87. fd = fopen(LOGFILE, "r");
  88. if (!fd)
  89. {
  90. printf("could not open log file '%s'\n", LOGFILE);
  91. return 1;
  92. }
  93. printf("<html>\n");
  94. printf("<head>\n");
  95. printf(" <title>Charon Thread Analysis</title>\n");
  96. printf(" <style>\n");
  97. printf(" body { font: 11px verdana,arial, helvetica, sans-serif }\n");
  98. printf(" td { font: 10px verdana,arial, helvetica, sans-serif;\n");
  99. printf(" text-align: center; padding: 0px 1px 0px 1px; background: #FFFF66 }\n");
  100. printf(" td.log { text-align: left; background: #FFFF66; white-space: nowrap }\n");
  101. printf(" td.idle { background: #FFFF66 }\n");
  102. printf(" td.init { background: #FFA522 }\n");
  103. printf(" td.auth { background: #90EE90 }\n");
  104. printf(" td.busy { background: #ADD8E6 }\n");
  105. printf(" td.retry { background: #7B68EE }\n");
  106. printf(" td.error { background: #FF6347 }\n");
  107. printf(" hr { background-color: #000000; border: 0; height: 1px; }\n");
  108. printf(" a:visited { color: #000000 }\n");
  109. printf(" a:link { color: #000000 }\n");
  110. printf(" a:hover { color: #0000FF }\n");
  111. printf(" </style>\n");
  112. printf("</head>\n");
  113. printf("<body>\n");
  114. printf(" <h1>Charon Thread Analysis</h1>\n");
  115. printf(" <table>\n");
  116. /* print table header */
  117. printf(" <tr>\n");
  118. printf(" <td class=\"log\">Timestamp</td>");
  119. for (th = 1 ; th <= THREADS; th++)
  120. {
  121. printf("<td>%02d</td>", th);
  122. }
  123. printf("<td class=\"init\">I</td><td class=\"auth\">A</td><td class=\"busy\">B</td>");
  124. for (th = 10; th <= (THREADS + 2); th += 5)
  125. {
  126. printf("<td class=\"busy\">%d</td>", (th == 100)? 99:th);
  127. }
  128. printf("\n");
  129. printf(" </tr>\n");
  130. while (readline(fd, line))
  131. {
  132. char *p_section, *p_charon, *p_thread, *p_log;
  133. p_section = strstr(line, "---");
  134. if (p_section)
  135. {
  136. printline(state, line);
  137. mode = MODE_ANY;
  138. if (section++ < 1)
  139. {
  140. continue;
  141. }
  142. else
  143. {
  144. break;
  145. }
  146. }
  147. p_charon = strstr(line, "charon");
  148. if (!p_charon)
  149. {
  150. continue;
  151. }
  152. /* determine thread */
  153. p_thread = p_charon + 8;
  154. th = atol(p_thread);
  155. /* determine log message */
  156. p_log = p_charon + 16;
  157. if (strstr(p_log, "received packet"))
  158. {
  159. if (mode == MODE_DEL)
  160. {
  161. printline(state, line);
  162. }
  163. mode = MODE_ADD;
  164. if (state[th] != STATE_IDLE)
  165. {
  166. state[th] = STATE_ERROR;
  167. }
  168. else
  169. {
  170. state[th] = STATE_BUSY;
  171. }
  172. }
  173. if (strstr(p_log, "sending packet"))
  174. {
  175. if (mode == MODE_ADD)
  176. {
  177. printline(state, line);
  178. }
  179. mode = MODE_DEL;
  180. if (state[th] == STATE_IDLE)
  181. {
  182. state[th] = STATE_ERROR;
  183. }
  184. else
  185. {
  186. state[th] = STATE_IDLE;
  187. }
  188. }
  189. if (strstr(p_log, "parsed IKE_SA_INIT request"))
  190. {
  191. if (state[th] != STATE_BUSY)
  192. {
  193. state[th] = STATE_ERROR;
  194. }
  195. else
  196. {
  197. state[th] = STATE_INIT;
  198. }
  199. }
  200. if (strstr(p_log, "parsed IKE_AUTH request"))
  201. {
  202. if (state[th] != STATE_BUSY)
  203. {
  204. state[th] = STATE_ERROR;
  205. }
  206. else
  207. {
  208. state[th] = STATE_AUTH;
  209. }
  210. }
  211. if (strstr(p_log, "already processing"))
  212. {
  213. if (state[th] != STATE_IDLE)
  214. {
  215. state[th] = STATE_ERROR;
  216. }
  217. else
  218. {
  219. state[th] = STATE_RETRY;
  220. }
  221. printline(state, line);
  222. mode = MODE_ANY;
  223. state[th] = STATE_IDLE;
  224. }
  225. }
  226. printf(" </table>\n");
  227. printf(" <p>\n");
  228. printf(" <table>\n");
  229. printf(" <tr>\n");
  230. printf(" <td class=\"init\">&nbsp;I&nbsp;</td><td>IKE_SA_INIT Thread &nbsp;</td>\n");
  231. printf(" <td class=\"auth\">&nbsp;A&nbsp;</td><td>IKE_AUTH Thread &nbsp;</td>\n");
  232. printf(" <td class=\"retry\">&nbsp;R&nbsp;</td><td>Retransmit Thread &nbsp;</td>\n");
  233. printf(" <td class=\"busy\">&nbsp;B&nbsp;</td><td>Busy Thread &nbsp;</td>\n");
  234. printf(" <td class=\"error\">&nbsp;E&nbsp;</td><td>State Error &nbsp;</td>\n");
  235. printf(" </tr>\n");
  236. printf(" </table>\n");
  237. printf(" <p>\n");
  238. printf(" <hr/>\n");
  239. printf(" <em>&copy; 2008\n");
  240. printf(" <a href=\"http://www.hsr.ch/?&L=1\" target=\"popup\">\n");
  241. printf(" HSR Hochschule f&uuml;r Technik Rapperswil</a>\n");
  242. printf(" </em>\n");
  243. printf("</body>\n");
  244. printf("</html>\n");
  245. fclose(fd);
  246. return 0;
  247. }