trema 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. data/.mono.rant +4107 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +4 -0
  4. data/Doxyfile +1679 -0
  5. data/GPL2 +339 -0
  6. data/Gemfile +22 -0
  7. data/Gemfile.lock +71 -0
  8. data/README.md +135 -0
  9. data/Rakefile +140 -0
  10. data/Rantfile +834 -0
  11. data/VERSION +1 -0
  12. data/build.rb +32 -0
  13. data/cruise.rb +389 -0
  14. data/features/example.dumper.feature +87 -0
  15. data/features/example.learning_switch.feature +39 -0
  16. data/features/example.list_switches.feature +38 -0
  17. data/features/example.message.echo_reply.feature +26 -0
  18. data/features/example.message.echo_request.feature +25 -0
  19. data/features/example.message.features_request.feature +84 -0
  20. data/features/example.message.hello.feature +25 -0
  21. data/features/example.message.set_config.feature +27 -0
  22. data/features/example.multi_learning_switch.feature +135 -0
  23. data/features/example.packetin_filter_config.feature +91 -0
  24. data/features/example.repeater_hub.feature +49 -0
  25. data/features/example.switch_monitor.feature +39 -0
  26. data/features/packetin_filter.feature +49 -0
  27. data/features/step_definitions/kill_steps.rb +30 -0
  28. data/features/step_definitions/log_steps.rb +90 -0
  29. data/features/step_definitions/misc_steps.rb +64 -0
  30. data/features/step_definitions/off_steps.rb +30 -0
  31. data/features/step_definitions/run_steps.rb +91 -0
  32. data/features/step_definitions/send_packets_steps.rb +42 -0
  33. data/features/step_definitions/show_stats_steps.rb +43 -0
  34. data/features/step_definitions/stats_steps.rb +39 -0
  35. data/features/support/env.rb +75 -0
  36. data/features/support/hooks.rb +8 -0
  37. data/features/switch_manager.feature +35 -0
  38. data/features/trema-config.feature +68 -0
  39. data/features/trema.dump_flows.feature +25 -0
  40. data/features/trema.feature +25 -0
  41. data/features/trema.kill.feature +53 -0
  42. data/features/trema.killall.feature +30 -0
  43. data/features/trema.reset_stats.feature +14 -0
  44. data/features/trema.run.feature +46 -0
  45. data/features/trema.send_packets.feature +56 -0
  46. data/features/trema.show_stats.feature +67 -0
  47. data/features/tutorial.hello_trema.feature +27 -0
  48. data/features/tutorial.packet_in.feature +47 -0
  49. data/features/tutorial.switch_info.feature +55 -0
  50. data/ruby/.gitignore +4 -0
  51. data/ruby/blocker.rb +78 -0
  52. data/ruby/extconf.rb +71 -0
  53. data/ruby/sub-process.rb +291 -0
  54. data/ruby/trema/action-common.c +60 -0
  55. data/ruby/trema/action-common.h +42 -0
  56. data/ruby/trema/action-enqueue.c +161 -0
  57. data/ruby/trema/action-enqueue.h +40 -0
  58. data/ruby/trema/action-output.c +169 -0
  59. data/ruby/trema/action-output.h +42 -0
  60. data/ruby/trema/action-set-dl-dst.c +131 -0
  61. data/ruby/trema/action-set-dl-dst.h +44 -0
  62. data/ruby/trema/action-set-dl-src.c +131 -0
  63. data/ruby/trema/action-set-dl-src.h +44 -0
  64. data/ruby/trema/action-set-nw-dst.c +135 -0
  65. data/ruby/trema/action-set-nw-dst.h +42 -0
  66. data/ruby/trema/action-set-nw-src.c +140 -0
  67. data/ruby/trema/action-set-nw-src.h +42 -0
  68. data/ruby/trema/action-set-nw-tos.c +124 -0
  69. data/ruby/trema/action-set-nw-tos.h +42 -0
  70. data/ruby/trema/action-set-tp-dst.c +122 -0
  71. data/ruby/trema/action-set-tp-dst.h +42 -0
  72. data/ruby/trema/action-set-tp-src.c +124 -0
  73. data/ruby/trema/action-set-tp-src.h +42 -0
  74. data/ruby/trema/action-set-vlan-pcp.c +128 -0
  75. data/ruby/trema/action-set-vlan-pcp.h +42 -0
  76. data/ruby/trema/action-set-vlan-vid.c +125 -0
  77. data/ruby/trema/action-set-vlan-vid.h +42 -0
  78. data/ruby/trema/action-strip-vlan.c +81 -0
  79. data/ruby/trema/action-strip-vlan.h +42 -0
  80. data/ruby/trema/action-vendor.c +121 -0
  81. data/ruby/trema/action-vendor.h +42 -0
  82. data/ruby/trema/aggregate-stats-reply.rb +70 -0
  83. data/ruby/trema/app.rb +112 -0
  84. data/ruby/trema/barrier-reply.c +99 -0
  85. data/ruby/trema/barrier-reply.h +46 -0
  86. data/ruby/trema/barrier-request.c +108 -0
  87. data/ruby/trema/barrier-request.h +44 -0
  88. data/ruby/trema/cli.rb +269 -0
  89. data/ruby/trema/command.rb +40 -0
  90. data/ruby/trema/command/dump_flows.rb +62 -0
  91. data/ruby/trema/command/kill.rb +71 -0
  92. data/ruby/trema/command/killall.rb +56 -0
  93. data/ruby/trema/command/reset_stats.rb +61 -0
  94. data/ruby/trema/command/ruby.rb +55 -0
  95. data/ruby/trema/command/run.rb +120 -0
  96. data/ruby/trema/command/send_packets.rb +130 -0
  97. data/ruby/trema/command/shell.rb +61 -0
  98. data/ruby/trema/command/show_stats.rb +84 -0
  99. data/ruby/trema/command/usage.rb +61 -0
  100. data/ruby/trema/command/version.rb +39 -0
  101. data/ruby/trema/controller.c +595 -0
  102. data/ruby/trema/controller.h +44 -0
  103. data/ruby/trema/controller.rb +81 -0
  104. data/ruby/trema/daemon.rb +167 -0
  105. data/ruby/trema/dsl.rb +34 -0
  106. data/ruby/trema/dsl/configuration.rb +153 -0
  107. data/ruby/trema/dsl/context.rb +71 -0
  108. data/ruby/trema/dsl/link.rb +41 -0
  109. data/ruby/trema/dsl/parser.rb +70 -0
  110. data/ruby/trema/dsl/run.rb +49 -0
  111. data/ruby/trema/dsl/runner.rb +165 -0
  112. data/ruby/trema/dsl/stanza.rb +53 -0
  113. data/ruby/trema/dsl/switch.rb +78 -0
  114. data/ruby/trema/dsl/syntax-error.rb +33 -0
  115. data/ruby/trema/dsl/syntax.rb +109 -0
  116. data/ruby/trema/dsl/vhost.rb +108 -0
  117. data/ruby/trema/dsl/vswitch.rb +47 -0
  118. data/ruby/trema/echo-reply.c +107 -0
  119. data/ruby/trema/echo-reply.h +42 -0
  120. data/ruby/trema/echo-request.c +140 -0
  121. data/ruby/trema/echo-request.h +42 -0
  122. data/ruby/trema/error.c +253 -0
  123. data/ruby/trema/error.h +44 -0
  124. data/ruby/trema/exact-match.rb +36 -0
  125. data/ruby/trema/executables.rb +95 -0
  126. data/ruby/trema/features-reply.c +238 -0
  127. data/ruby/trema/features-reply.h +60 -0
  128. data/ruby/trema/features-request.c +109 -0
  129. data/ruby/trema/features-request.h +44 -0
  130. data/ruby/trema/flow-removed.c +275 -0
  131. data/ruby/trema/flow-removed.h +46 -0
  132. data/ruby/trema/flow-stats-reply.rb +109 -0
  133. data/ruby/trema/flow.rb +56 -0
  134. data/ruby/trema/get-config-reply.c +159 -0
  135. data/ruby/trema/get-config-reply.h +52 -0
  136. data/ruby/trema/get-config-request.c +107 -0
  137. data/ruby/trema/get-config-request.h +44 -0
  138. data/ruby/trema/hello.c +110 -0
  139. data/ruby/trema/hello.h +44 -0
  140. data/ruby/trema/host.rb +257 -0
  141. data/ruby/trema/ip.rb +101 -0
  142. data/ruby/trema/link.rb +176 -0
  143. data/ruby/trema/list-switches-reply.c +46 -0
  144. data/ruby/trema/list-switches-reply.h +40 -0
  145. data/ruby/trema/logger.c +162 -0
  146. data/ruby/trema/logger.h +44 -0
  147. data/ruby/trema/mac.rb +151 -0
  148. data/ruby/trema/match.c +594 -0
  149. data/ruby/trema/match.h +36 -0
  150. data/ruby/trema/monkey-patch/integer.rb +35 -0
  151. data/ruby/trema/monkey-patch/integer/base-conversions.rb +36 -0
  152. data/ruby/trema/monkey-patch/integer/ranges.rb +51 -0
  153. data/ruby/trema/monkey-patch/module.rb +33 -0
  154. data/ruby/trema/monkey-patch/module/deprecation.rb +41 -0
  155. data/ruby/trema/monkey-patch/string.rb +33 -0
  156. data/ruby/trema/monkey-patch/string/inflectors.rb +54 -0
  157. data/ruby/trema/network-component.rb +153 -0
  158. data/ruby/trema/ofctl.rb +62 -0
  159. data/ruby/trema/open-vswitch.rb +154 -0
  160. data/ruby/trema/openflow-error.c +191 -0
  161. data/ruby/trema/openflow-error.h +53 -0
  162. data/ruby/trema/openflow-switch.rb +88 -0
  163. data/ruby/trema/ordered-hash.rb +74 -0
  164. data/ruby/trema/packet-queue.rb +178 -0
  165. data/ruby/trema/packet_in.c +736 -0
  166. data/ruby/trema/packet_in.h +46 -0
  167. data/ruby/trema/packetin-filter.rb +126 -0
  168. data/ruby/trema/path.rb +135 -0
  169. data/ruby/trema/phost.rb +69 -0
  170. data/ruby/trema/port-mod.c +226 -0
  171. data/ruby/trema/port-mod.h +36 -0
  172. data/ruby/trema/port-stats-reply.rb +111 -0
  173. data/ruby/trema/port-status.c +156 -0
  174. data/ruby/trema/port-status.h +45 -0
  175. data/ruby/trema/port.c +295 -0
  176. data/ruby/trema/port.h +47 -0
  177. data/ruby/trema/process.rb +76 -0
  178. data/ruby/trema/queue-get-config-reply.c +200 -0
  179. data/ruby/trema/queue-get-config-reply.h +47 -0
  180. data/ruby/trema/queue-get-config-request.c +141 -0
  181. data/ruby/trema/queue-get-config-request.h +44 -0
  182. data/ruby/trema/queue-stats-reply.rb +78 -0
  183. data/ruby/trema/set-config.c +171 -0
  184. data/ruby/trema/set-config.h +44 -0
  185. data/ruby/trema/shell.rb +39 -0
  186. data/ruby/trema/shell/down.rb +39 -0
  187. data/ruby/trema/shell/killall.rb +40 -0
  188. data/ruby/trema/shell/link.rb +61 -0
  189. data/ruby/trema/shell/reset_stats.rb +50 -0
  190. data/ruby/trema/shell/run.rb +67 -0
  191. data/ruby/trema/shell/send_packets.rb +42 -0
  192. data/ruby/trema/shell/show_stats.rb +49 -0
  193. data/ruby/trema/shell/up.rb +43 -0
  194. data/ruby/trema/shell/vhost.rb +44 -0
  195. data/ruby/trema/shell/vswitch.rb +49 -0
  196. data/ruby/trema/stats-helper.rb +65 -0
  197. data/ruby/trema/stats-reply.c +483 -0
  198. data/ruby/trema/stats-reply.h +53 -0
  199. data/ruby/trema/stats-request.c +634 -0
  200. data/ruby/trema/stats-request.h +42 -0
  201. data/ruby/trema/switch-daemon.rb +74 -0
  202. data/ruby/trema/switch-disconnected.c +40 -0
  203. data/ruby/trema/switch-disconnected.h +38 -0
  204. data/ruby/trema/switch-manager.rb +121 -0
  205. data/ruby/trema/switch.rb +37 -0
  206. data/ruby/trema/table-stats-reply.rb +87 -0
  207. data/ruby/trema/timers.rb +97 -0
  208. data/ruby/trema/trema.c +122 -0
  209. data/ruby/trema/tremashark.rb +39 -0
  210. data/ruby/trema/util.rb +84 -0
  211. data/ruby/trema/vendor-request.c +193 -0
  212. data/ruby/trema/vendor-request.h +44 -0
  213. data/ruby/trema/vendor-stats-reply.rb +62 -0
  214. data/ruby/trema/vendor.c +152 -0
  215. data/ruby/trema/vendor.h +52 -0
  216. data/ruby/trema/version.rb +30 -0
  217. data/spec/spec_helper.rb +153 -0
  218. data/spec/support/openflow-message.rb +94 -0
  219. data/spec/trema/action-enqueue_spec.rb +100 -0
  220. data/spec/trema/action-output_spec.rb +116 -0
  221. data/spec/trema/action-set-dl-dst_spec.rb +95 -0
  222. data/spec/trema/action-set-dl-src_spec.rb +92 -0
  223. data/spec/trema/action-set-nw-dst_spec.rb +96 -0
  224. data/spec/trema/action-set-nw-src_spec.rb +97 -0
  225. data/spec/trema/action-set-nw-tos_spec.rb +88 -0
  226. data/spec/trema/action-set-tp-dst_spec.rb +88 -0
  227. data/spec/trema/action-set-tp-src_spec.rb +88 -0
  228. data/spec/trema/action-set-vlan-pcp_spec.rb +91 -0
  229. data/spec/trema/action-set-vlan-vid_spec.rb +91 -0
  230. data/spec/trema/action-strip-vlan_spec.rb +57 -0
  231. data/spec/trema/action-vendor_spec.rb +90 -0
  232. data/spec/trema/app_spec.rb +90 -0
  233. data/spec/trema/barrier-reply_spec.rb +45 -0
  234. data/spec/trema/barrier-request_spec.rb +83 -0
  235. data/spec/trema/cli_spec.rb +160 -0
  236. data/spec/trema/controller_spec.rb +100 -0
  237. data/spec/trema/dsl/configuration_spec.rb +122 -0
  238. data/spec/trema/dsl/link_spec.rb +54 -0
  239. data/spec/trema/dsl/run_spec.rb +78 -0
  240. data/spec/trema/dsl/runner_spec.rb +239 -0
  241. data/spec/trema/dsl/switch_spec.rb +77 -0
  242. data/spec/trema/dsl/syntax_spec.rb +121 -0
  243. data/spec/trema/dsl/vhost_spec.rb +148 -0
  244. data/spec/trema/dsl/vswitch_spec.rb +90 -0
  245. data/spec/trema/echo-reply_spec.rb +49 -0
  246. data/spec/trema/echo-request_spec.rb +75 -0
  247. data/spec/trema/error_spec.rb +142 -0
  248. data/spec/trema/executables_spec.rb +75 -0
  249. data/spec/trema/features-reply_spec.rb +57 -0
  250. data/spec/trema/features-request_spec.rb +66 -0
  251. data/spec/trema/flow-removed_spec.rb +146 -0
  252. data/spec/trema/get-config-reply_spec.rb +43 -0
  253. data/spec/trema/get-config-request_spec.rb +82 -0
  254. data/spec/trema/hello_spec.rb +49 -0
  255. data/spec/trema/host_spec.rb +193 -0
  256. data/spec/trema/link_spec.rb +64 -0
  257. data/spec/trema/list-switches-reply_spec.rb +48 -0
  258. data/spec/trema/logger_spec.rb +48 -0
  259. data/spec/trema/mac_spec.rb +115 -0
  260. data/spec/trema/match_spec.rb +113 -0
  261. data/spec/trema/open-vswitch_spec.rb +123 -0
  262. data/spec/trema/openflow-error_spec.rb +141 -0
  263. data/spec/trema/openflow-switch_spec.rb +56 -0
  264. data/spec/trema/packet-in_spec.rb +168 -0
  265. data/spec/trema/packet-out_spec.rb +128 -0
  266. data/spec/trema/packetin-filter_spec.rb +41 -0
  267. data/spec/trema/port-mod_spec.rb +101 -0
  268. data/spec/trema/port-status_spec.rb +108 -0
  269. data/spec/trema/port_spec.rb +61 -0
  270. data/spec/trema/process_spec.rb +71 -0
  271. data/spec/trema/queue-get-config-reply_spec.rb +66 -0
  272. data/spec/trema/queue-get-config-request_spec.rb +69 -0
  273. data/spec/trema/set-config_spec.rb +80 -0
  274. data/spec/trema/shell/vhost_spec.rb +57 -0
  275. data/spec/trema/shell/vswitch_spec.rb +89 -0
  276. data/spec/trema/stats-reply_spec.rb +306 -0
  277. data/spec/trema/stats-request_spec.rb +151 -0
  278. data/spec/trema/switch-disconnected_spec.rb +58 -0
  279. data/spec/trema/switch-manager_spec.rb +43 -0
  280. data/spec/trema/tremashark_spec.rb +41 -0
  281. data/spec/trema/util_spec.rb +93 -0
  282. data/spec/trema/vendor-request_spec.rb +79 -0
  283. data/src/examples/cbench_switch/README +21 -0
  284. data/src/examples/cbench_switch/cbench-switch.rb +39 -0
  285. data/src/examples/cbench_switch/cbench_switch.c +68 -0
  286. data/src/examples/dumper/dumper.c +370 -0
  287. data/src/examples/dumper/dumper.conf +7 -0
  288. data/src/examples/dumper/dumper.rb +196 -0
  289. data/src/examples/hello_trema/README +13 -0
  290. data/src/examples/hello_trema/hello_trema.c +51 -0
  291. data/src/examples/hello_trema/hello_trema.conf +3 -0
  292. data/src/examples/hello_trema/hello_trema.rb +35 -0
  293. data/src/examples/learning_switch/README +15 -0
  294. data/src/examples/learning_switch/fdb.rb +112 -0
  295. data/src/examples/learning_switch/learning-switch.rb +88 -0
  296. data/src/examples/learning_switch/learning_switch.c +236 -0
  297. data/src/examples/learning_switch/learning_switch.conf +18 -0
  298. data/src/examples/list_switches/README +19 -0
  299. data/src/examples/list_switches/list-switches.rb +45 -0
  300. data/src/examples/list_switches/list_switches.c +81 -0
  301. data/src/examples/list_switches/list_switches.conf +15 -0
  302. data/src/examples/match_compare/match-compare.conf +30 -0
  303. data/src/examples/match_compare/match-compare.rb +99 -0
  304. data/src/examples/multi_learning_switch/README +14 -0
  305. data/src/examples/multi_learning_switch/multi-learning-switch.rb +96 -0
  306. data/src/examples/multi_learning_switch/multi_learning_switch.c +296 -0
  307. data/src/examples/multi_learning_switch/multi_learning_switch.conf +17 -0
  308. data/src/examples/openflow_message/README +11 -0
  309. data/src/examples/openflow_message/echo-reply.rb +59 -0
  310. data/src/examples/openflow_message/echo-request.rb +58 -0
  311. data/src/examples/openflow_message/echo_reply.c +70 -0
  312. data/src/examples/openflow_message/echo_request.c +70 -0
  313. data/src/examples/openflow_message/example.rb +63 -0
  314. data/src/examples/openflow_message/features-request.rb +97 -0
  315. data/src/examples/openflow_message/features_request.c +168 -0
  316. data/src/examples/openflow_message/hello.c +70 -0
  317. data/src/examples/openflow_message/hello.rb +58 -0
  318. data/src/examples/openflow_message/set-config.rb +59 -0
  319. data/src/examples/openflow_message/set_config.c +70 -0
  320. data/src/examples/packet_in/README +15 -0
  321. data/src/examples/packet_in/packet_in.c +55 -0
  322. data/src/examples/packet_in/packet_in.conf +15 -0
  323. data/src/examples/packet_in/packet_in.rb +34 -0
  324. data/src/examples/packetin_filter_config/README +12 -0
  325. data/src/examples/packetin_filter_config/add_filter.c +73 -0
  326. data/src/examples/packetin_filter_config/delete_filter.c +65 -0
  327. data/src/examples/packetin_filter_config/delete_filter_strict.c +75 -0
  328. data/src/examples/packetin_filter_config/dump_filter.c +65 -0
  329. data/src/examples/packetin_filter_config/dump_filter_strict.c +75 -0
  330. data/src/examples/packetin_filter_config/packetin_filter_config.c +134 -0
  331. data/src/examples/packetin_filter_config/packetin_filter_config.conf +7 -0
  332. data/src/examples/packetin_filter_config/utils.c +102 -0
  333. data/src/examples/packetin_filter_config/utils.h +42 -0
  334. data/src/examples/repeater_hub/README +8 -0
  335. data/src/examples/repeater_hub/repeater-hub.rb +43 -0
  336. data/src/examples/repeater_hub/repeater-hub_spec.rb +156 -0
  337. data/src/examples/repeater_hub/repeater_hub.c +83 -0
  338. data/src/examples/repeater_hub/repeater_hub.conf +28 -0
  339. data/src/examples/switch_info/README +13 -0
  340. data/src/examples/switch_info/switch_info.c +80 -0
  341. data/src/examples/switch_info/switch_info.conf +3 -0
  342. data/src/examples/switch_info/switch_info.rb +46 -0
  343. data/src/examples/switch_monitor/switch-monitor.conf +3 -0
  344. data/src/examples/switch_monitor/switch-monitor.rb +58 -0
  345. data/src/examples/switch_monitor/switch_monitor.c +154 -0
  346. data/src/examples/traffic_monitor/counter.c +74 -0
  347. data/src/examples/traffic_monitor/counter.h +48 -0
  348. data/src/examples/traffic_monitor/counter.rb +46 -0
  349. data/src/examples/traffic_monitor/fdb.c +76 -0
  350. data/src/examples/traffic_monitor/fdb.h +50 -0
  351. data/src/examples/traffic_monitor/fdb.rb +44 -0
  352. data/src/examples/traffic_monitor/traffic-monitor.rb +100 -0
  353. data/src/examples/traffic_monitor/traffic_monitor.c +163 -0
  354. data/src/examples/traffic_monitor/traffic_monitor.conf +16 -0
  355. data/src/lib/arp.h +61 -0
  356. data/src/lib/bool.h +49 -0
  357. data/src/lib/buffer.c +305 -0
  358. data/src/lib/buffer.h +56 -0
  359. data/src/lib/byteorder.c +547 -0
  360. data/src/lib/byteorder.h +110 -0
  361. data/src/lib/checks.h +42 -0
  362. data/src/lib/daemon.c +302 -0
  363. data/src/lib/daemon.h +42 -0
  364. data/src/lib/doubly_linked_list.c +281 -0
  365. data/src/lib/doubly_linked_list.h +88 -0
  366. data/src/lib/ether.c +48 -0
  367. data/src/lib/ether.h +94 -0
  368. data/src/lib/etherip.h +46 -0
  369. data/src/lib/event_handler.c +389 -0
  370. data/src/lib/event_handler.h +64 -0
  371. data/src/lib/hash_table.c +417 -0
  372. data/src/lib/hash_table.h +138 -0
  373. data/src/lib/icmp.h +74 -0
  374. data/src/lib/igmp.h +50 -0
  375. data/src/lib/ipv4.h +50 -0
  376. data/src/lib/linked_list.c +199 -0
  377. data/src/lib/linked_list.h +84 -0
  378. data/src/lib/log.c +402 -0
  379. data/src/lib/log.h +78 -0
  380. data/src/lib/match.h +84 -0
  381. data/src/lib/match_table.c +608 -0
  382. data/src/lib/match_table.h +51 -0
  383. data/src/lib/message_queue.c +143 -0
  384. data/src/lib/message_queue.h +61 -0
  385. data/src/lib/messenger.c +1714 -0
  386. data/src/lib/messenger.h +145 -0
  387. data/src/lib/openflow_application_interface.c +1673 -0
  388. data/src/lib/openflow_application_interface.h +329 -0
  389. data/src/lib/openflow_message.c +4051 -0
  390. data/src/lib/openflow_message.h +288 -0
  391. data/src/lib/openflow_service_interface.h +59 -0
  392. data/src/lib/packet_info.c +230 -0
  393. data/src/lib/packet_info.h +209 -0
  394. data/src/lib/packet_parser.c +502 -0
  395. data/src/lib/packetin_filter_interface.c +294 -0
  396. data/src/lib/packetin_filter_interface.h +127 -0
  397. data/src/lib/persistent_storage.c +480 -0
  398. data/src/lib/persistent_storage.h +46 -0
  399. data/src/lib/stat.c +213 -0
  400. data/src/lib/stat.h +44 -0
  401. data/src/lib/tcp.h +67 -0
  402. data/src/lib/timer.c +350 -0
  403. data/src/lib/timer.h +53 -0
  404. data/src/lib/trema.c +710 -0
  405. data/src/lib/trema.h +79 -0
  406. data/src/lib/trema_private.c +177 -0
  407. data/src/lib/trema_private.h +60 -0
  408. data/src/lib/trema_wrapper.c +56 -0
  409. data/src/lib/trema_wrapper.h +64 -0
  410. data/src/lib/udp.h +43 -0
  411. data/src/lib/utility.c +515 -0
  412. data/src/lib/utility.h +67 -0
  413. data/src/lib/wrapper.c +100 -0
  414. data/src/lib/wrapper.h +76 -0
  415. data/src/packetin_filter/README +17 -0
  416. data/src/packetin_filter/packetin_filter.c +575 -0
  417. data/src/switch_manager/README +20 -0
  418. data/src/switch_manager/cookie_table.c +292 -0
  419. data/src/switch_manager/cookie_table.h +72 -0
  420. data/src/switch_manager/dpid_table.c +110 -0
  421. data/src/switch_manager/dpid_table.h +46 -0
  422. data/src/switch_manager/management_interface.h +44 -0
  423. data/src/switch_manager/ofpmsg_recv.c +482 -0
  424. data/src/switch_manager/ofpmsg_recv.h +42 -0
  425. data/src/switch_manager/ofpmsg_send.c +235 -0
  426. data/src/switch_manager/ofpmsg_send.h +50 -0
  427. data/src/switch_manager/secure_channel_listener.c +281 -0
  428. data/src/switch_manager/secure_channel_listener.h +42 -0
  429. data/src/switch_manager/secure_channel_receiver.c +126 -0
  430. data/src/switch_manager/secure_channel_receiver.h +43 -0
  431. data/src/switch_manager/secure_channel_sender.c +126 -0
  432. data/src/switch_manager/secure_channel_sender.h +43 -0
  433. data/src/switch_manager/service_interface.c +181 -0
  434. data/src/switch_manager/service_interface.h +46 -0
  435. data/src/switch_manager/switch.c +538 -0
  436. data/src/switch_manager/switch.h +51 -0
  437. data/src/switch_manager/switch_manager.c +448 -0
  438. data/src/switch_manager/switch_manager.h +63 -0
  439. data/src/switch_manager/switchinfo.h +72 -0
  440. data/src/switch_manager/xid_table.c +184 -0
  441. data/src/switch_manager/xid_table.h +56 -0
  442. data/src/tremashark/README +78 -0
  443. data/src/tremashark/packet_capture.c +357 -0
  444. data/src/tremashark/pcap_private.h +47 -0
  445. data/src/tremashark/pcap_queue.c +197 -0
  446. data/src/tremashark/pcap_queue.h +58 -0
  447. data/src/tremashark/plugin/.gitignore +6 -0
  448. data/src/tremashark/plugin/packet-trema/.gitignore +5 -0
  449. data/src/tremashark/plugin/packet-trema/Makefile +77 -0
  450. data/src/tremashark/plugin/packet-trema/Makefile.am +110 -0
  451. data/src/tremashark/plugin/packet-trema/Makefile.common +31 -0
  452. data/src/tremashark/plugin/packet-trema/moduleinfo.h +41 -0
  453. data/src/tremashark/plugin/packet-trema/packet-trema.c +1659 -0
  454. data/src/tremashark/plugin/packet-trema/plugin.c +31 -0
  455. data/src/tremashark/plugin/user_dlts +2 -0
  456. data/src/tremashark/queue.c +168 -0
  457. data/src/tremashark/queue.h +60 -0
  458. data/src/tremashark/stdin_relay.c +257 -0
  459. data/src/tremashark/syslog_relay.c +247 -0
  460. data/src/tremashark/tremashark.c +556 -0
  461. data/trema +93 -0
  462. data/trema-config +61 -0
  463. data/unittests/buffer_stubs.c +74 -0
  464. data/unittests/cmockery_trema.c +123 -0
  465. data/unittests/cmockery_trema.h +96 -0
  466. data/unittests/lib/buffer_test.c +370 -0
  467. data/unittests/lib/byteorder_test.c +1717 -0
  468. data/unittests/lib/daemon_test.c +664 -0
  469. data/unittests/lib/doubly_linked_list_test.c +346 -0
  470. data/unittests/lib/ether_test.c +127 -0
  471. data/unittests/lib/hash_table_test.c +278 -0
  472. data/unittests/lib/linked_list_test.c +343 -0
  473. data/unittests/lib/log_test.c +459 -0
  474. data/unittests/lib/match_table_test.c +1509 -0
  475. data/unittests/lib/message_queue_test.c +379 -0
  476. data/unittests/lib/messenger_test.c +438 -0
  477. data/unittests/lib/openflow_application_interface_test.c +3488 -0
  478. data/unittests/lib/openflow_message_test.c +7337 -0
  479. data/unittests/lib/packet_info_test.c +544 -0
  480. data/unittests/lib/packet_parser_test.c +703 -0
  481. data/unittests/lib/packetin_filter_interface_test.c +723 -0
  482. data/unittests/lib/persistent_storage_test.c +802 -0
  483. data/unittests/lib/stat_test.c +291 -0
  484. data/unittests/lib/test_packets/arp_rep.cap +0 -0
  485. data/unittests/lib/test_packets/arp_req.cap +0 -0
  486. data/unittests/lib/test_packets/icmp_echo_rep.cap +0 -0
  487. data/unittests/lib/test_packets/icmp_echo_req.cap +0 -0
  488. data/unittests/lib/test_packets/igmp_query_v2.cap +0 -0
  489. data/unittests/lib/test_packets/ipx.cap +0 -0
  490. data/unittests/lib/test_packets/lldp.cap +0 -0
  491. data/unittests/lib/test_packets/lldp_over_ip.cap +0 -0
  492. data/unittests/lib/test_packets/tcp.cap +0 -0
  493. data/unittests/lib/test_packets/tcp_syn.cap +0 -0
  494. data/unittests/lib/test_packets/udp.cap +0 -0
  495. data/unittests/lib/test_packets/udp_frag_head.cap +0 -0
  496. data/unittests/lib/test_packets/udp_frag_next.cap +0 -0
  497. data/unittests/lib/test_packets/vtag_icmp_echo_rep.cap +0 -0
  498. data/unittests/lib/test_packets/vtag_icmp_echo_req.cap +0 -0
  499. data/unittests/lib/timer_test.c +248 -0
  500. data/unittests/lib/trema_private_test.c +323 -0
  501. data/unittests/lib/trema_test.c +985 -0
  502. data/unittests/lib/utility_test.c +628 -0
  503. data/unittests/lib/wrapper_test.c +201 -0
  504. data/unittests/packetin_filter/packetin_filter_test.c +477 -0
  505. data/unittests/switch_manager/switch_manager_test.c +1178 -0
  506. data/unittests/wrapper_stubs.c +39 -0
  507. data/vendor/.gitignore +6 -0
  508. data/vendor/README +30 -0
  509. data/vendor/cmockery-20110428.tar.gz +0 -0
  510. data/vendor/oflops-0.03.tar.gz +0 -0
  511. data/vendor/oflops_no_snmp+1.0.0.patch +340 -0
  512. data/vendor/openflow-1.0.0.tar.gz +0 -0
  513. data/vendor/openflow.git.tar.gz +0 -0
  514. data/vendor/openvswitch-1.2.2.tar.gz +0 -0
  515. data/vendor/ruby-ifconfig-1.2/COPYING +340 -0
  516. data/vendor/ruby-ifconfig-1.2/Changelog +16 -0
  517. data/vendor/ruby-ifconfig-1.2/INSTALL +239 -0
  518. data/vendor/ruby-ifconfig-1.2/README +38 -0
  519. data/vendor/ruby-ifconfig-1.2/Rakefile +14 -0
  520. data/vendor/ruby-ifconfig-1.2/TODO +8 -0
  521. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/darwin.txt +17 -0
  522. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/dragonflybsd.txt +10 -0
  523. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/dragonflybsd_netstat.txt +14 -0
  524. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/freebsd.txt +17 -0
  525. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/freebsd_netstat.txt +24 -0
  526. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/linux.txt +60 -0
  527. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/linux_ethernet.txt +20 -0
  528. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/netbsd.txt +10 -0
  529. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/openbsd.txt +36 -0
  530. data/vendor/ruby-ifconfig-1.2/ifconfig_examples/sunos.txt +10 -0
  531. data/vendor/ruby-ifconfig-1.2/lib/ifconfig.rb +71 -0
  532. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/ifconfig.rb +72 -0
  533. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/interface_types.rb +69 -0
  534. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/bsd/network_types.rb +3 -0
  535. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/ifconfig.rb +84 -0
  536. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/interface_types.rb +130 -0
  537. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/common/network_types.rb +49 -0
  538. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/ifconfig.rb +43 -0
  539. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/interface_types.rb +112 -0
  540. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/linux/network_types.rb +55 -0
  541. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/ifconfig.rb +38 -0
  542. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/interface_types.rb +77 -0
  543. data/vendor/ruby-ifconfig-1.2/lib/ifconfig/sunos/network_types.rb +4 -0
  544. data/vendor/ruby-ifconfig-1.2/setup.rb +1306 -0
  545. data/vendor/ruby-ifconfig-1.2/test/test_bsd.rb +35 -0
  546. data/vendor/ruby-ifconfig-1.2/test/test_darwin.rb +33 -0
  547. data/vendor/ruby-ifconfig-1.2/test/test_dragonflybsd.rb +35 -0
  548. data/vendor/ruby-ifconfig-1.2/test/test_helper.rb +4 -0
  549. data/vendor/ruby-ifconfig-1.2/test/test_linux.rb +31 -0
  550. data/vendor/ruby-ifconfig-1.2/test/test_netbsd.rb +33 -0
  551. data/vendor/ruby-ifconfig-1.2/test/test_openbsd.rb +33 -0
  552. data/vendor/ruby-ifconfig-1.2/test/test_sunos.rb +35 -0
  553. data/vendor/ruby-ifconfig-1.2/test/unit/tc_darwin.rb +40 -0
  554. data/vendor/ruby-ifconfig-1.2/test/unit/tc_dragonflybsd.rb +39 -0
  555. data/vendor/ruby-ifconfig-1.2/test/unit/tc_freebsd.rb +40 -0
  556. data/vendor/ruby-ifconfig-1.2/test/unit/tc_linux.rb +49 -0
  557. data/vendor/ruby-ifconfig-1.2/test/unit/tc_netbsd.rb +39 -0
  558. data/vendor/ruby-ifconfig-1.2/test/unit/tc_openbsd.rb +39 -0
  559. data/vendor/ruby-ifconfig-1.2/test/unit/tc_sunos.rb +44 -0
  560. metadata +856 -0
@@ -0,0 +1,46 @@
1
+ /*
2
+ * A persistent data storage library
3
+ *
4
+ * Author: Yasunobu Chiba
5
+ *
6
+ * Copyright (C) 2008-2012 NEC Corporation
7
+ *
8
+ * This program is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License, version 2, as
10
+ * published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+
23
+ #ifndef PERSISTENT_STORAGE_H
24
+ #define PERSISTENT_STORAGE_H
25
+
26
+
27
+ #include "bool.h"
28
+
29
+
30
+ bool init_persistent_storage();
31
+ bool finalize_persistent_storage();
32
+ bool clear_persistent_storage();
33
+ bool set_value( const char *key, const char *value );
34
+ bool get_value( const char *key, char *value, const size_t length );
35
+ bool delete_key_value( const char *key );
36
+
37
+
38
+ #endif // PERSISTENT_STORAGE_H
39
+
40
+
41
+ /*
42
+ * Local variables:
43
+ * c-basic-offset: 2
44
+ * indent-tabs-mode: nil
45
+ * End:
46
+ */
@@ -0,0 +1,213 @@
1
+ /*
2
+ * Author: Yasunobu Chiba
3
+ *
4
+ * Copyright (C) 2008-2012 NEC Corporation
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License, version 2, as
8
+ * published by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License along
16
+ * with this program; if not, write to the Free Software Foundation, Inc.,
17
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ */
19
+
20
+
21
+ #include <assert.h>
22
+ #include <inttypes.h>
23
+ #include <pthread.h>
24
+ #include "bool.h"
25
+ #include "hash_table.h"
26
+ #include "log.h"
27
+ #include "stat.h"
28
+ #include "utility.h"
29
+ #include "wrapper.h"
30
+
31
+
32
+ #ifdef UNIT_TESTING
33
+
34
+ // Allow static functions to be called from unit tests.
35
+ #define static
36
+
37
+ #ifdef debug
38
+ #undef debug
39
+ #endif
40
+ #define debug mock_debug
41
+ void mock_debug( const char *format, ... );
42
+
43
+ #ifdef info
44
+ #undef info
45
+ #endif
46
+ #define info mock_info
47
+ void mock_info( const char *format, ... );
48
+
49
+ #ifdef warn
50
+ #undef warn
51
+ #endif
52
+ #define warn mock_warn
53
+ void mock_warn( const char *format, ... );
54
+
55
+ #ifdef error
56
+ #undef error
57
+ #endif
58
+ #define error mock_error
59
+ void mock_error( const char *format, ... );
60
+
61
+ #endif // UNIT_TESTING
62
+
63
+ static hash_table *stats = NULL;
64
+ static pthread_mutex_t stats_table_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
65
+
66
+
67
+ typedef struct {
68
+ char key[ STAT_KEY_LENGTH ];
69
+ uint64_t value;
70
+ } stat_entry;
71
+
72
+
73
+ static void
74
+ create_stats_table() {
75
+ assert( stats == NULL );
76
+ stats = create_hash( compare_string, hash_string );
77
+ assert( stats != NULL );
78
+ }
79
+
80
+
81
+ static void
82
+ delete_stats_table() {
83
+ hash_iterator iter;
84
+ hash_entry *e;
85
+
86
+ assert( stats != NULL );
87
+
88
+ init_hash_iterator( stats, &iter );
89
+ while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
90
+ void *value = delete_hash_entry( stats, e->key );
91
+ xfree( value );
92
+ }
93
+ delete_hash( stats );
94
+ stats = NULL;
95
+ }
96
+
97
+
98
+ bool
99
+ init_stat() {
100
+ debug( "Initializing statistics collector." );
101
+
102
+ if ( stats != NULL ) {
103
+ warn( "Statistics collector is already initialized. Reinitializing." );
104
+ finalize_stat();
105
+ }
106
+
107
+ pthread_mutex_lock( &stats_table_mutex );
108
+ create_stats_table();
109
+ pthread_mutex_unlock( &stats_table_mutex );
110
+
111
+ return true;
112
+ }
113
+
114
+
115
+ bool
116
+ finalize_stat() {
117
+ debug( "Finalizing statistics collector." );
118
+
119
+ assert( stats != NULL );
120
+
121
+ pthread_mutex_lock( &stats_table_mutex );
122
+ delete_stats_table();
123
+ pthread_mutex_unlock( &stats_table_mutex );
124
+
125
+ return true;
126
+ }
127
+
128
+
129
+ bool
130
+ add_stat_entry( const char *key ) {
131
+ assert( key != NULL );
132
+
133
+ pthread_mutex_lock( &stats_table_mutex );
134
+
135
+ stat_entry *entry = lookup_hash_entry( stats, key );
136
+
137
+ if ( entry != NULL ) {
138
+ error( "Statistic entry for %s already exists.", key );
139
+ pthread_mutex_unlock( &stats_table_mutex );
140
+ return false;
141
+ }
142
+
143
+ entry = xmalloc( sizeof( stat_entry ) );
144
+ entry->value = 0;
145
+ strncpy( entry->key, key, STAT_KEY_LENGTH );
146
+ entry->key[ STAT_KEY_LENGTH - 1 ] = '\0';
147
+
148
+ insert_hash_entry( stats, entry->key, entry );
149
+
150
+ pthread_mutex_unlock( &stats_table_mutex );
151
+
152
+ return true;
153
+ }
154
+
155
+
156
+ void
157
+ increment_stat( const char *key ) {
158
+ assert( key != NULL );
159
+ assert( stats != NULL );
160
+
161
+ pthread_mutex_lock( &stats_table_mutex );
162
+
163
+ stat_entry *entry = lookup_hash_entry( stats, key );
164
+ if ( entry == NULL ) {
165
+ if ( add_stat_entry( key ) == false ) {
166
+ pthread_mutex_unlock( &stats_table_mutex );
167
+ return;
168
+ }
169
+ entry = lookup_hash_entry( stats, key );
170
+ }
171
+
172
+ assert( entry != NULL );
173
+
174
+ ( entry->value )++;
175
+
176
+ pthread_mutex_unlock( &stats_table_mutex );
177
+ }
178
+
179
+
180
+ void
181
+ dump_stats() {
182
+ assert( stats != NULL );
183
+
184
+ int n_stats = 0;
185
+ hash_iterator iter;
186
+ hash_entry *e;
187
+
188
+ pthread_mutex_lock( &stats_table_mutex );
189
+
190
+ info( "Statistics:" );
191
+
192
+ init_hash_iterator( stats, &iter );
193
+ while ( ( e = iterate_hash_next( &iter ) ) != NULL ) {
194
+ stat_entry *st = e->value;
195
+ info( "%s: %" PRIu64, st->key, st->value );
196
+ n_stats++;
197
+ }
198
+
199
+ if ( n_stats == 0 ) {
200
+ info( "No statistics found." );
201
+ }
202
+
203
+ pthread_mutex_unlock( &stats_table_mutex );
204
+ }
205
+
206
+
207
+ /*
208
+ * Local variables:
209
+ * c-basic-offset: 2
210
+ * indent-tabs-mode: nil
211
+ * End:
212
+ */
213
+
@@ -0,0 +1,44 @@
1
+ /*
2
+ * A statistics collector library.
3
+ *
4
+ * Author: Yasunobu Chiba
5
+ *
6
+ * Copyright (C) 2008-2012 NEC Corporation
7
+ *
8
+ * This program is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License, version 2, as
10
+ * published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+
23
+ #ifndef STAT_H
24
+
25
+
26
+ #define STAT_KEY_LENGTH 256
27
+
28
+
29
+ bool init_stat( void );
30
+ bool finalize_stat( void );
31
+ bool add_stat_entry( const char *key );
32
+ void increment_stat( const char *key );
33
+ void dump_stats();
34
+
35
+
36
+ #endif // STAT_H
37
+
38
+
39
+ /*
40
+ * Local variables:
41
+ * c-basic-offset: 2
42
+ * indent-tabs-mode: nil
43
+ * End:
44
+ */
@@ -0,0 +1,67 @@
1
+ /*
2
+ * TCP header definitions
3
+ *
4
+ * Author: Kazuya Suzuki
5
+ *
6
+ * Copyright (C) 2008-2012 NEC Corporation
7
+ *
8
+ * This program is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License, version 2, as
10
+ * published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License along
18
+ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+ */
21
+
22
+
23
+ #ifndef TCP_H
24
+ #define TCP_H
25
+
26
+
27
+ #include <endian.h>
28
+
29
+
30
+ typedef struct tcp_header {
31
+ uint16_t src_port;
32
+ uint16_t dst_port;
33
+ uint32_t seq_no;
34
+ uint32_t ack_no;
35
+ #if ( __BYTE_ORDER == __BIG_ENDIAN )
36
+ uint8_t offset:4,
37
+ reserved:4;
38
+ #else // _LITTLE_ENDIAN
39
+ uint8_t reserved:4,
40
+ offset:4;
41
+ #endif
42
+ uint8_t flags;
43
+ uint16_t window;
44
+ uint16_t csum;
45
+ uint16_t urgent;
46
+ } tcp_header_t;
47
+
48
+
49
+ #define TCP_FLAG_FIN ( 1 << 0 )
50
+ #define TCP_FLAG_SYN ( 1 << 1 )
51
+ #define TCP_FLAG_RST ( 1 << 2 )
52
+ #define TCP_FLAG_PSH ( 1 << 3 )
53
+ #define TCP_FLAG_ACK ( 1 << 4 )
54
+ #define TCP_FLAG_URG ( 1 << 5 )
55
+ #define TCP_FLAG_ECE ( 1 << 6 )
56
+ #define TCP_FLAG_CWR ( 1 << 7 )
57
+
58
+
59
+ #endif // TCP_H
60
+
61
+
62
+ /*
63
+ * Local variables:
64
+ * c-basic-offset: 2
65
+ * indent-tabs-mode: nil
66
+ * End:
67
+ */
@@ -0,0 +1,350 @@
1
+ /*
2
+ * Author: Yasuhito Takamiya <yasuhito@gmail.com>
3
+ *
4
+ * Copyright (C) 2008-2012 NEC Corporation
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License, version 2, as
8
+ * published by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License along
16
+ * with this program; if not, write to the Free Software Foundation, Inc.,
17
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ */
19
+
20
+
21
+ #include <assert.h>
22
+ #include <errno.h>
23
+ #include <limits.h>
24
+ #include "doubly_linked_list.h"
25
+ #include "log.h"
26
+ #include "timer.h"
27
+ #include "wrapper.h"
28
+
29
+
30
+ #ifdef UNIT_TESTING
31
+
32
+ #ifdef clock_gettime
33
+ #undef clock_gettime
34
+ #endif
35
+ #define clock_gettime mock_clock_gettime
36
+ extern int mock_clock_gettime( clockid_t clk_id, struct timespec *tp );
37
+
38
+ #ifdef error
39
+ #undef error
40
+ #endif
41
+ #define error mock_error
42
+ void mock_error( const char *format, ... );
43
+
44
+ #ifdef debug
45
+ #undef debug
46
+ #endif
47
+ #define debug mock_debug
48
+ void mock_debug( const char *format, ... );
49
+
50
+ #define static
51
+
52
+ #endif // UNIT_TESTING
53
+
54
+
55
+ typedef struct timer_callback_info {
56
+ timer_callback function;
57
+ struct timespec expires_at;
58
+ struct timespec interval;
59
+ void *user_data;
60
+ } timer_callback_info;
61
+
62
+
63
+ static dlist_element *timer_callbacks = NULL;
64
+
65
+
66
+ bool
67
+ _init_timer() {
68
+ if ( timer_callbacks != NULL ) {
69
+ error( "Called init_timer twice." );
70
+ return false;
71
+ }
72
+
73
+ timer_callbacks = create_dlist();
74
+
75
+ debug( "Initializing timer callbacks ( timer_callbacks = %p ).", timer_callbacks );
76
+ return true;
77
+ }
78
+ bool ( *init_timer )( void ) = _init_timer;
79
+
80
+
81
+ bool
82
+ _finalize_timer() {
83
+ dlist_element *e;
84
+
85
+ debug( "Deleting timer callbacks ( timer_callbacks = %p ).", timer_callbacks );
86
+
87
+ if ( timer_callbacks != NULL ) {
88
+ for ( e = timer_callbacks->next; e; e = e->next ) {
89
+ xfree( e->data );
90
+ }
91
+ delete_dlist( timer_callbacks );
92
+ timer_callbacks = NULL;
93
+ }
94
+ else {
95
+ error( "All timer callbacks are already deleted or not created yet." );
96
+ }
97
+ return true;
98
+ }
99
+ bool ( *finalize_timer )( void ) = _finalize_timer;
100
+
101
+
102
+ #define VALID_TIMESPEC( _a ) \
103
+ ( ( ( _a )->tv_sec > 0 || ( _a )->tv_nsec > 0 ) ? 1 : 0 )
104
+
105
+ #define ADD_TIMESPEC( _a, _b, _return ) \
106
+ do { \
107
+ ( _return )->tv_sec = ( _a )->tv_sec + ( _b )->tv_sec; \
108
+ ( _return )->tv_nsec = ( _a )->tv_nsec + ( _b )->tv_nsec; \
109
+ if ( ( _return )->tv_nsec >= 1000000000 ) { \
110
+ ( _return )->tv_sec++; \
111
+ ( _return )->tv_nsec -= 1000000000; \
112
+ } \
113
+ } \
114
+ while ( 0 )
115
+
116
+ #define SUB_TIMESPEC( _a, _b, _return ) \
117
+ do { \
118
+ ( _return )->tv_sec = ( _a )->tv_sec - ( _b )->tv_sec; \
119
+ ( _return )->tv_nsec = ( _a )->tv_nsec - ( _b )->tv_nsec; \
120
+ if ( ( _return )->tv_nsec < 0 ) { \
121
+ ( _return )->tv_sec--; \
122
+ ( _return )->tv_nsec += 1000000000; \
123
+ } \
124
+ } \
125
+ while ( 0 )
126
+
127
+ #define TIMESPEC_LESS_THEN( _a, _b ) \
128
+ ( ( ( _a )->tv_sec == ( _b )->tv_sec ) ? \
129
+ ( ( _a )->tv_nsec < ( _b )->tv_nsec ) : \
130
+ ( ( _a )->tv_sec < ( _b )->tv_sec ) )
131
+
132
+ #define TIMESPEC_TO_MICROSECONDS( _a, _b ) \
133
+ do { \
134
+ struct timespec round = { 0, 999 }; \
135
+ ADD_TIMESPEC( _a, &round, &round ); \
136
+ ( *( _b ) = ( int ) ( round.tv_sec * 1000000 + round.tv_nsec / 1000 ) ); \
137
+ } \
138
+ while ( 0 )
139
+
140
+
141
+ static void
142
+ on_timer( timer_callback_info *callback, struct timespec *now ) {
143
+ assert( callback != NULL );
144
+ assert( callback->function != NULL );
145
+
146
+ debug( "Executing a timer event ( function = %p, expires_at = %u.%09u, interval = %u.%09u, user_data = %p ).",
147
+ callback->function, callback->expires_at.tv_sec, callback->expires_at.tv_nsec,
148
+ callback->interval.tv_sec, callback->interval.tv_nsec, callback->user_data );
149
+
150
+ if ( VALID_TIMESPEC( &callback->expires_at ) ) {
151
+ callback->function( callback->user_data );
152
+ if ( VALID_TIMESPEC( &callback->interval ) ) {
153
+ ADD_TIMESPEC( &callback->expires_at, &callback->interval, &callback->expires_at );
154
+ if ( TIMESPEC_LESS_THEN( &callback->expires_at, now ) ) {
155
+ callback->expires_at.tv_sec = now->tv_sec;
156
+ callback->expires_at.tv_nsec = now->tv_nsec;
157
+ }
158
+ }
159
+ else {
160
+ callback->expires_at.tv_sec = 0;
161
+ callback->expires_at.tv_nsec = 0;
162
+ callback->function = NULL;
163
+ }
164
+ debug( "Set expires_at value to %u.%09u.", callback->expires_at.tv_sec, callback->expires_at.tv_nsec );
165
+ }
166
+ else {
167
+ error( "Invalid expires_at value." );
168
+ }
169
+ }
170
+
171
+
172
+ static void
173
+ insert_timer_callback( timer_callback_info *new_cb ) {
174
+ assert( timer_callbacks != NULL );
175
+ dlist_element *element, *last = timer_callbacks;
176
+ for ( element = timer_callbacks->next; element != NULL; element = element->next ) {
177
+ timer_callback_info *cb = element->data;
178
+ if ( TIMESPEC_LESS_THEN( &new_cb->expires_at, &cb->expires_at ) ) {
179
+ insert_before_dlist( element, new_cb );
180
+ return;
181
+ }
182
+ last = element;
183
+ }
184
+ insert_after_dlist( last, new_cb );
185
+ }
186
+
187
+
188
+ void
189
+ _execute_timer_events( int *next_timeout_usec ) {
190
+ assert( next_timeout_usec != NULL );
191
+ struct timespec now;
192
+ timer_callback_info *callback;
193
+ dlist_element *element, *element_next;
194
+
195
+ debug( "Executing timer events ( timer_callbacks = %p ).", timer_callbacks );
196
+
197
+ assert( clock_gettime( CLOCK_MONOTONIC, &now ) == 0 );
198
+ assert( timer_callbacks != NULL );
199
+
200
+ for ( element = timer_callbacks->next; element; element = element_next ) {
201
+ element_next = element->next;
202
+ callback = element->data;
203
+ if ( callback->function != NULL ) {
204
+ if ( TIMESPEC_LESS_THEN( &now, &callback->expires_at ) ) {
205
+ break;
206
+ }
207
+ on_timer( callback, &now );
208
+ }
209
+ delete_dlist_element( element );
210
+ if ( callback->function == NULL ) {
211
+ xfree( callback );
212
+ }
213
+ else {
214
+ insert_timer_callback( callback );
215
+ }
216
+ }
217
+
218
+ struct timespec max_timeout = { ( INT_MAX / 1000000 ), 0 };
219
+ struct timespec min_timeout = { 0, 0 };
220
+ if ( timer_callbacks->next == NULL ) {
221
+ TIMESPEC_TO_MICROSECONDS( &max_timeout, next_timeout_usec );
222
+ }
223
+ else {
224
+ callback = timer_callbacks->next->data;
225
+ if ( TIMESPEC_LESS_THEN( &callback->expires_at, &now ) ) {
226
+ TIMESPEC_TO_MICROSECONDS( &min_timeout, next_timeout_usec );
227
+ }
228
+ else {
229
+ struct timespec timeout;
230
+ SUB_TIMESPEC( &callback->expires_at, &now, &timeout );
231
+ if ( TIMESPEC_LESS_THEN( &timeout, &max_timeout ) ) {
232
+ TIMESPEC_TO_MICROSECONDS( &timeout, next_timeout_usec );
233
+ }
234
+ else {
235
+ TIMESPEC_TO_MICROSECONDS( &max_timeout, next_timeout_usec );
236
+ }
237
+ }
238
+ }
239
+ }
240
+ void ( *execute_timer_events )( int * ) = _execute_timer_events;
241
+
242
+
243
+ bool
244
+ _add_timer_event_callback( struct itimerspec *interval, timer_callback callback, void *user_data ) {
245
+ assert( interval != NULL );
246
+ assert( callback != NULL );
247
+
248
+ debug( "Adding a timer event callback ( interval = %u.%09u, initial expiration = %u.%09u, callback = %p, user_data = %p ).",
249
+ interval->it_interval.tv_sec, interval->it_interval.tv_nsec,
250
+ interval->it_value.tv_sec, interval->it_value.tv_nsec, callback, user_data );
251
+
252
+ timer_callback_info *cb;
253
+ struct timespec now;
254
+
255
+ cb = xmalloc( sizeof( timer_callback_info ) );
256
+ memset( cb, 0, sizeof( timer_callback_info ) );
257
+ cb->function = callback;
258
+ cb->user_data = user_data;
259
+
260
+ if ( clock_gettime( CLOCK_MONOTONIC, &now ) != 0 ) {
261
+ error( "Failed to retrieve monotonic time ( %s [%d] ).", strerror( errno ), errno );
262
+ xfree( cb );
263
+ return false;
264
+ }
265
+
266
+ cb->interval = interval->it_interval;
267
+
268
+ if ( VALID_TIMESPEC( &interval->it_value ) ) {
269
+ ADD_TIMESPEC( &now, &interval->it_value, &cb->expires_at );
270
+ }
271
+ else if ( VALID_TIMESPEC( &interval->it_interval ) ) {
272
+ ADD_TIMESPEC( &now, &interval->it_interval, &cb->expires_at );
273
+ }
274
+ else {
275
+ error( "Timer must not be zero when a timer event is added." );
276
+ xfree( cb );
277
+ return false;
278
+ }
279
+
280
+ debug( "Set an initial expiration time to %u.%09u.", now.tv_sec, now.tv_nsec );
281
+
282
+ assert( timer_callbacks != NULL );
283
+ insert_timer_callback( cb );
284
+
285
+ return true;
286
+ }
287
+ bool ( *add_timer_event_callback )( struct itimerspec *interval, timer_callback callback, void *user_data ) = _add_timer_event_callback;
288
+
289
+
290
+ bool
291
+ _add_periodic_event_callback( const time_t seconds, timer_callback callback, void *user_data ) {
292
+ assert( callback != NULL );
293
+
294
+ debug( "Adding a periodic event callback ( interval = %u, callback = %p, user_data = %p ).",
295
+ seconds, callback, user_data );
296
+
297
+ struct itimerspec interval;
298
+
299
+ interval.it_value.tv_sec = 0;
300
+ interval.it_value.tv_nsec = 0;
301
+ interval.it_interval.tv_sec = seconds;
302
+ interval.it_interval.tv_nsec = 0;
303
+
304
+ return add_timer_event_callback( &interval, callback, user_data );
305
+ }
306
+ bool ( *add_periodic_event_callback )( const time_t seconds, timer_callback callback, void *user_data ) = _add_periodic_event_callback;
307
+
308
+
309
+ bool
310
+ _delete_timer_event( timer_callback callback, void *user_data ) {
311
+ assert( callback != NULL );
312
+
313
+ debug( "Deleting a timer event ( callback = %p, user_data = %p ).", callback, user_data );
314
+
315
+ dlist_element *e;
316
+
317
+ if ( timer_callbacks == NULL ) {
318
+ debug( "All timer callbacks are already deleted or not created yet." );
319
+ return false;
320
+ }
321
+
322
+ for ( e = timer_callbacks->next; e; e = e->next ) {
323
+ timer_callback_info *cb = e->data;
324
+ if ( cb->function == callback && cb->user_data == user_data ) {
325
+ debug( "Deleting a callback ( callback = %p, user_data = %p ).", callback, user_data );
326
+ //xfree( cb );
327
+ //delete_dlist_element( e );
328
+ cb->function = NULL;
329
+ cb->user_data = NULL;
330
+ cb->expires_at.tv_sec = 0;
331
+ cb->expires_at.tv_nsec = 0;
332
+ cb->interval.tv_sec = 0;
333
+ cb->interval.tv_nsec = 0;
334
+ return true;
335
+ }
336
+ }
337
+
338
+ error( "No registered timer event callback found." );
339
+
340
+ return false;
341
+ }
342
+ bool ( *delete_timer_event )( timer_callback callback, void *user_data ) = _delete_timer_event;
343
+
344
+
345
+ /*
346
+ * Local variables:
347
+ * c-basic-offset: 2
348
+ * indent-tabs-mode: nil
349
+ * End:
350
+ */