Sipper 1.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 (326) hide show
  1. data/sipper/README.rb +26 -0
  2. data/sipper/b2bua_controller.rb +163 -0
  3. data/sipper/b2bua_session_mixin.rb +24 -0
  4. data/sipper/base_controller.rb +425 -0
  5. data/sipper/bin/common.rb +42 -0
  6. data/sipper/bin/generate.rb +70 -0
  7. data/sipper/bin/project.rb +44 -0
  8. data/sipper/bin/run.rb +85 -0
  9. data/sipper/bin/run_smoke.rb +8 -0
  10. data/sipper/config/log4r.xml +71 -0
  11. data/sipper/controller_class_loader.rb +29 -0
  12. data/sipper/controller_selector.rb +119 -0
  13. data/sipper/controllers/invite_controller.rb +30 -0
  14. data/sipper/controllers/order.yaml +3 -0
  15. data/sipper/custom_message.rb +4 -0
  16. data/sipper/detached_session.rb +11 -0
  17. data/sipper/docs/manual.txt +1621 -0
  18. data/sipper/generators/README +12 -0
  19. data/sipper/generators/gen_controller.rb +228 -0
  20. data/sipper/generators/gen_project.rb +45 -0
  21. data/sipper/generators/gen_test.rb +72 -0
  22. data/sipper/generators/project_template_dir/Rakefile +56 -0
  23. data/sipper/generators/project_template_dir/config/sipper.cfg +31 -0
  24. data/sipper/generators/project_template_dir/controllers/README.txt +2 -0
  25. data/sipper/generators/project_template_dir/dot_sipper.proj +2 -0
  26. data/sipper/generators/project_template_dir/logs/README.txt +2 -0
  27. data/sipper/generators/project_template_dir/tests/README.txt +2 -0
  28. data/sipper/lib/smc/statemap.rb +194 -0
  29. data/sipper/logs/dialog_info_store +0 -0
  30. data/sipper/logs/r.cmd +6 -0
  31. data/sipper/logs/r.sh +6 -0
  32. data/sipper/media/sipper_media_client.rb +268 -0
  33. data/sipper/media/sipper_media_event.rb +43 -0
  34. data/sipper/media/sipper_media_manager.rb +145 -0
  35. data/sipper/media/sipper_media_proxy.rb +60 -0
  36. data/sipper/media/sipper_offer_answer.rb +285 -0
  37. data/sipper/message.rb +512 -0
  38. data/sipper/modified_pattern_formatter.rb +119 -0
  39. data/sipper/proxy_controller.rb +143 -0
  40. data/sipper/registration.rb +52 -0
  41. data/sipper/request.rb +109 -0
  42. data/sipper/response.rb +123 -0
  43. data/sipper/ruby_ext/module.rb +27 -0
  44. data/sipper/ruby_ext/mutable_class.rb +17 -0
  45. data/sipper/ruby_ext/object.rb +38 -0
  46. data/sipper/ruby_ext/pqueue.rb +190 -0
  47. data/sipper/ruby_ext/snapshot.rb +201 -0
  48. data/sipper/ruby_ext/string.rb +18 -0
  49. data/sipper/ruby_ext/time.rb +9 -0
  50. data/sipper/run/run_sipper1.rb +28 -0
  51. data/sipper/run/run_sipper2.rb +56 -0
  52. data/sipper/sdp/sdp.rb +257 -0
  53. data/sipper/sdp/sdp_generator.rb +131 -0
  54. data/sipper/sdp/sdp_parser.rb +136 -0
  55. data/sipper/session.rb +1952 -0
  56. data/sipper/session_manager.rb +170 -0
  57. data/sipper/session_recorder.rb +190 -0
  58. data/sipper/session_state/DialogState.sm +54 -0
  59. data/sipper/session_state/DialogState_sm.rb +337 -0
  60. data/sipper/session_state/dialog_routes.rb +141 -0
  61. data/sipper/sip_headers/header.rb +632 -0
  62. data/sipper/sip_headers/sipuri.rb +352 -0
  63. data/sipper/sip_logger.rb +65 -0
  64. data/sipper/sip_message_router.rb +231 -0
  65. data/sipper/sip_test_driver_controller.rb +10 -0
  66. data/sipper/sipper.rb +329 -0
  67. data/sipper/sipper_assertions.rb +21 -0
  68. data/sipper/sipper_configurator.rb +376 -0
  69. data/sipper/sipper_http/sipper_http_request_dispatcher.rb +71 -0
  70. data/sipper/sipper_http/sipper_http_response.rb +25 -0
  71. data/sipper/stray_message_manager.rb +40 -0
  72. data/sipper/test_completion_signaling_helper.rb +77 -0
  73. data/sipper/transaction/Ict.sm +59 -0
  74. data/sipper/transaction/Ict_sm.rb +430 -0
  75. data/sipper/transaction/Ist.sm +74 -0
  76. data/sipper/transaction/Ist_sm.rb +460 -0
  77. data/sipper/transaction/Nict.sm +51 -0
  78. data/sipper/transaction/Nict_sm.rb +325 -0
  79. data/sipper/transaction/Nist.sm +59 -0
  80. data/sipper/transaction/Nist_sm.rb +356 -0
  81. data/sipper/transaction/invite_client_transaction.rb +274 -0
  82. data/sipper/transaction/invite_server_transaction.rb +319 -0
  83. data/sipper/transaction/non_invite_client_transaction.rb +230 -0
  84. data/sipper/transaction/non_invite_server_transaction.rb +263 -0
  85. data/sipper/transaction/state_machine_wrapper.rb +58 -0
  86. data/sipper/transaction/transaction.rb +212 -0
  87. data/sipper/transport/base_transport.rb +84 -0
  88. data/sipper/transport/rel_unrel.rb +19 -0
  89. data/sipper/transport/transport_and_route_resolver.rb +67 -0
  90. data/sipper/transport/udp_transport.rb +156 -0
  91. data/sipper/transport_manager.rb +33 -0
  92. data/sipper/udp_session.rb +17 -0
  93. data/sipper/util/command_element.rb +62 -0
  94. data/sipper/util/compact_converter.rb +50 -0
  95. data/sipper/util/counter.rb +26 -0
  96. data/sipper/util/digest/digest_authorizer.rb +204 -0
  97. data/sipper/util/expectation_parser.rb +164 -0
  98. data/sipper/util/locator.rb +31 -0
  99. data/sipper/util/message_fill.rb +58 -0
  100. data/sipper/util/persistence/ps_sipper_map.rb +63 -0
  101. data/sipper/util/persistence/sipper_map.rb +41 -0
  102. data/sipper/util/sipper_util.rb +305 -0
  103. data/sipper/util/timer/sip_timer_helper.rb +26 -0
  104. data/sipper/util/timer/timer_manager.rb +80 -0
  105. data/sipper/util/timer/timer_task.rb +56 -0
  106. data/sipper/util/validations.rb +44 -0
  107. data/sipper/version.rb +10 -0
  108. data/sipper_test/_test_media_uas.rb +79 -0
  109. data/sipper_test/base_test_case.rb +31 -0
  110. data/sipper_test/c_134.txt +7 -0
  111. data/sipper_test/driven_sip_test_case.rb +96 -0
  112. data/sipper_test/gold.txt +10 -0
  113. data/sipper_test/gold_res.txt +8 -0
  114. data/sipper_test/gold_sub.txt +9 -0
  115. data/sipper_test/hello_sipper.au +0 -0
  116. data/sipper_test/in_sipper.au +0 -0
  117. data/sipper_test/nonrr_proxy.rb +17 -0
  118. data/sipper_test/order_tests.yaml +4 -0
  119. data/sipper_test/rake_res.txt +399 -0
  120. data/sipper_test/rr_proxy.rb +17 -0
  121. data/sipper_test/run_test.cmd +94 -0
  122. data/sipper_test/sip_test_case.rb +104 -0
  123. data/sipper_test/test2xx_retransmission.rb +80 -0
  124. data/sipper_test/test2xx_retransmission_with_limit.rb +81 -0
  125. data/sipper_test/test2xx_retransmission_with_nist.rb +91 -0
  126. data/sipper_test/test2xx_retransmission_with_txns.rb +94 -0
  127. data/sipper_test/test_address_header.rb +66 -0
  128. data/sipper_test/test_b2bua1.rb +130 -0
  129. data/sipper_test/test_b2bua2.rb +120 -0
  130. data/sipper_test/test_b2bua3.rb +160 -0
  131. data/sipper_test/test_b2bua4.rb +130 -0
  132. data/sipper_test/test_base_controller.rb +110 -0
  133. data/sipper_test/test_base_transport.rb +37 -0
  134. data/sipper_test/test_cancel.rb +21 -0
  135. data/sipper_test/test_cancel_after2xx.rb +81 -0
  136. data/sipper_test/test_cancel_retransmission.rb +105 -0
  137. data/sipper_test/test_cancel_with481.rb +83 -0
  138. data/sipper_test/test_cancel_with487.rb +70 -0
  139. data/sipper_test/test_cancel_with_ist_without_nist.rb +99 -0
  140. data/sipper_test/test_cancel_with_nist.rb +84 -0
  141. data/sipper_test/test_cancel_without487.rb +77 -0
  142. data/sipper_test/test_command_element.rb +38 -0
  143. data/sipper_test/test_compact_converter.rb +33 -0
  144. data/sipper_test/test_controller_class_loader.rb +37 -0
  145. data/sipper_test/test_controller_selector.rb +53 -0
  146. data/sipper_test/test_controller_using_compact_headers.rb +74 -0
  147. data/sipper_test/test_controller_using_header_order.rb +85 -0
  148. data/sipper_test/test_controller_using_ict.rb +64 -0
  149. data/sipper_test/test_controller_using_ict_with_non_success.rb +72 -0
  150. data/sipper_test/test_controller_using_ict_with_tcbh.rb +24 -0
  151. data/sipper_test/test_controller_using_ict_with_tcbh_no_action.rb +24 -0
  152. data/sipper_test/test_controller_using_ist.rb +70 -0
  153. data/sipper_test/test_controller_using_ist_with_tcbh.rb +24 -0
  154. data/sipper_test/test_controller_using_nict.rb +115 -0
  155. data/sipper_test/test_controller_using_nict_with_tcbh.rb +24 -0
  156. data/sipper_test/test_controller_using_nist.rb +63 -0
  157. data/sipper_test/test_controller_using_pre_existing_rs0.rb +73 -0
  158. data/sipper_test/test_controller_using_pre_existing_rs1.rb +75 -0
  159. data/sipper_test/test_controller_using_pre_existing_rs2.rb +71 -0
  160. data/sipper_test/test_controller_using_route_set.rb +86 -0
  161. data/sipper_test/test_controller_with_sdp.rb +80 -0
  162. data/sipper_test/test_controllers/cancel/order.yaml +2 -0
  163. data/sipper_test/test_controllers/cancel/uac_cancel_controller.rb +35 -0
  164. data/sipper_test/test_controllers/cancel/uas_cancel_controller.rb +25 -0
  165. data/sipper_test/test_controllers/class_loading/ordered/first_ordered_controller.rb +5 -0
  166. data/sipper_test/test_controllers/class_loading/ordered/order.yaml +3 -0
  167. data/sipper_test/test_controllers/class_loading/ordered/recond_ordered_controller.rb +6 -0
  168. data/sipper_test/test_controllers/class_loading/ordered/second_ordered_controller.rb +6 -0
  169. data/sipper_test/test_controllers/class_loading/unordered/first_unordered_controller.rb +7 -0
  170. data/sipper_test/test_controllers/class_loading/unordered/second_unordered_controller.rb +6 -0
  171. data/sipper_test/test_controllers/ctrl_trhandler/lib/transport_filters/my_transport_handler.rb +22 -0
  172. data/sipper_test/test_controllers/ctrl_trhandler/uac_tr_handler_controller.rb +27 -0
  173. data/sipper_test/test_controllers/ctrl_trhandler/uas_tr_handler_controller.rb +21 -0
  174. data/sipper_test/test_controllers/ete/order.yaml +1 -0
  175. data/sipper_test/test_controllers/ete/uac_controller.rb +39 -0
  176. data/sipper_test/test_controllers/ete/uas_controller.rb +34 -0
  177. data/sipper_test/test_controllers/extensions/extension_uac_controller.rb +24 -0
  178. data/sipper_test/test_controllers/extensions/extension_uas_controller.rb +35 -0
  179. data/sipper_test/test_controllers/extensions/lib/sipper_extensions/my_from_extension.rb +16 -0
  180. data/sipper_test/test_controllers/ict_tcbh/lib/transaction_handlers/app_ict_handler.rb +23 -0
  181. data/sipper_test/test_controllers/ict_tcbh/uac_ict_tcbh_controller.rb +27 -0
  182. data/sipper_test/test_controllers/ict_tcbh/uac_ict_tcbh_no_action_controller.rb +28 -0
  183. data/sipper_test/test_controllers/ict_tcbh/uas_ict_tcbh_controller.rb +29 -0
  184. data/sipper_test/test_controllers/ict_tcbh/uas_ict_tcbh_no_action_controller.rb +31 -0
  185. data/sipper_test/test_controllers/ist_tcbh/lib/app_ist_handler.rb +13 -0
  186. data/sipper_test/test_controllers/ist_tcbh/uac_ist_tcbh_controller.rb +22 -0
  187. data/sipper_test/test_controllers/ist_tcbh/uas_ist_tcbh_controller.rb +31 -0
  188. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/in_order.yaml +2 -0
  189. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/my_transport_handler1.rb +21 -0
  190. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/my_transport_handler2.rb +21 -0
  191. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/out_order.yaml +2 -0
  192. data/sipper_test/test_controllers/multi_trhandlers/uac_multi_tr_handler_controller.rb +27 -0
  193. data/sipper_test/test_controllers/multi_trhandlers/uas_multi_tr_handler_controller.rb +29 -0
  194. data/sipper_test/test_controllers/multiple/lib/blank_test.rb +2 -0
  195. data/sipper_test/test_controllers/multiple/uac_info_controller.rb +21 -0
  196. data/sipper_test/test_controllers/multiple/uac_msg_controller.rb +20 -0
  197. data/sipper_test/test_controllers/multiple/uas_info_controller.rb +15 -0
  198. data/sipper_test/test_controllers/multiple/uas_msg_controller.rb +14 -0
  199. data/sipper_test/test_controllers/nict_tcbh/lib/transaction_handlers/app_nict_handler.rb +13 -0
  200. data/sipper_test/test_controllers/nict_tcbh/uac_nict_tcbh_controller.rb +26 -0
  201. data/sipper_test/test_controllers/nict_tcbh/uas_nict_tcbh_controller.rb +20 -0
  202. data/sipper_test/test_controllers/state_machine_based/lib/CreditControl.sm +43 -0
  203. data/sipper_test/test_controllers/state_machine_based/lib/CreditControl_sm.rb +194 -0
  204. data/sipper_test/test_controllers/state_machine_based/order.yaml +1 -0
  205. data/sipper_test/test_controllers/state_machine_based/uac_message_controller.rb +34 -0
  206. data/sipper_test/test_controllers/state_machine_based/uas_message_controller.rb +44 -0
  207. data/sipper_test/test_controllers/stray_message/lib/sipper_extensions/my_stray_handler.rb +9 -0
  208. data/sipper_test/test_controllers/stray_message/stray_uac_controller.rb +24 -0
  209. data/sipper_test/test_controllers/stray_message/stray_uas_controller.rb +31 -0
  210. data/sipper_test/test_controllers/string/order.yaml +1 -0
  211. data/sipper_test/test_controllers/string/uac_controller.rb +29 -0
  212. data/sipper_test/test_controllers/string/uas_controller.rb +22 -0
  213. data/sipper_test/test_controllers/test_controller.rb +24 -0
  214. data/sipper_test/test_detached_session1.rb +78 -0
  215. data/sipper_test/test_dialog_routes.rb +139 -0
  216. data/sipper_test/test_digest_challenge1.rb +89 -0
  217. data/sipper_test/test_digest_challenge2.rb +90 -0
  218. data/sipper_test/test_dynamic_parse.rb +249 -0
  219. data/sipper_test/test_empty_sdp.rb +89 -0
  220. data/sipper_test/test_ete.rb +37 -0
  221. data/sipper_test/test_expectation_parser.rb +76 -0
  222. data/sipper_test/test_extensions.rb +28 -0
  223. data/sipper_test/test_freeze.rb +81 -0
  224. data/sipper_test/test_generated.rb +90 -0
  225. data/sipper_test/test_header_parameters.rb +75 -0
  226. data/sipper_test/test_header_parse.rb +141 -0
  227. data/sipper_test/test_http_client1.rb +84 -0
  228. data/sipper_test/test_http_client2.rb +90 -0
  229. data/sipper_test/test_ict_with_timeout.rb +62 -0
  230. data/sipper_test/test_in_dialog_request.rb +61 -0
  231. data/sipper_test/test_inline_controller.rb +67 -0
  232. data/sipper_test/test_invite_client_transaction.rb +272 -0
  233. data/sipper_test/test_invite_replace.rb +147 -0
  234. data/sipper_test/test_invite_retransmission.rb +90 -0
  235. data/sipper_test/test_invite_server_transaction.rb +208 -0
  236. data/sipper_test/test_lower_cseq.rb +79 -0
  237. data/sipper_test/test_media.rb +52 -0
  238. data/sipper_test/test_message.rb +392 -0
  239. data/sipper_test/test_method_specific_response_handling.rb +81 -0
  240. data/sipper_test/test_multi_homed1.rb +127 -0
  241. data/sipper_test/test_multi_homed2.rb +109 -0
  242. data/sipper_test/test_multi_homed_duplicate.rb +87 -0
  243. data/sipper_test/test_multi_homed_with_detached.rb +88 -0
  244. data/sipper_test/test_multiple.rb +49 -0
  245. data/sipper_test/test_multiple_contacts.rb +89 -0
  246. data/sipper_test/test_non2xx_retransmission_with_ist.rb +87 -0
  247. data/sipper_test/test_non_invite_client_transaction.rb +210 -0
  248. data/sipper_test/test_non_invite_retransmission.rb +91 -0
  249. data/sipper_test/test_non_invite_server_transaction.rb +202 -0
  250. data/sipper_test/test_offer_answer_prack.rb +103 -0
  251. data/sipper_test/test_pickup.rb +258 -0
  252. data/sipper_test/test_prack.rb +105 -0
  253. data/sipper_test/test_prack_store_and_dispatch.rb +101 -0
  254. data/sipper_test/test_prack_timer.rb +105 -0
  255. data/sipper_test/test_ps_sipper_map.rb +56 -0
  256. data/sipper_test/test_re_invite_uas_ongoing_ict.rb +81 -0
  257. data/sipper_test/test_re_invite_uas_ongoing_ist.rb +84 -0
  258. data/sipper_test/test_re_invite_with_ongoing_ict.rb +101 -0
  259. data/sipper_test/test_re_invite_with_ongoing_ist.rb +89 -0
  260. data/sipper_test/test_recorder_swap.rb +157 -0
  261. data/sipper_test/test_refer.rb +121 -0
  262. data/sipper_test/test_registeration_clearing.rb +97 -0
  263. data/sipper_test/test_registrar.rb +109 -0
  264. data/sipper_test/test_registration_controller.rb +73 -0
  265. data/sipper_test/test_registration_timeout.rb +90 -0
  266. data/sipper_test/test_remote_controller.rb +39 -0
  267. data/sipper_test/test_remote_target_update_on2xx.rb +140 -0
  268. data/sipper_test/test_request.rb +106 -0
  269. data/sipper_test/test_response.rb +40 -0
  270. data/sipper_test/test_response_without_to_tag.rb +92 -0
  271. data/sipper_test/test_rport.rb +88 -0
  272. data/sipper_test/test_sdp.rb +91 -0
  273. data/sipper_test/test_sdp_parser.rb +145 -0
  274. data/sipper_test/test_session.rb +276 -0
  275. data/sipper_test/test_session_callback_handler.rb +68 -0
  276. data/sipper_test/test_session_lifetime.rb +66 -0
  277. data/sipper_test/test_session_manager.rb +141 -0
  278. data/sipper_test/test_session_recorder.rb +145 -0
  279. data/sipper_test/test_session_state_user_defined.rb +84 -0
  280. data/sipper_test/test_session_states.rb +91 -0
  281. data/sipper_test/test_simple_dialog_state.rb +86 -0
  282. data/sipper_test/test_simple_re_invite.rb +86 -0
  283. data/sipper_test/test_sip_uri.rb +234 -0
  284. data/sipper_test/test_sipper_util.rb +45 -0
  285. data/sipper_test/test_smc_controller.rb +17 -0
  286. data/sipper_test/test_smoke.rb +80 -0
  287. data/sipper_test/test_stray.rb +28 -0
  288. data/sipper_test/test_stray_inline.rb +89 -0
  289. data/sipper_test/test_stray_res_acked.rb +103 -0
  290. data/sipper_test/test_stray_respond.rb +104 -0
  291. data/sipper_test/test_stray_retry.rb +92 -0
  292. data/sipper_test/test_stray_retry_failure.rb +93 -0
  293. data/sipper_test/test_stray_retry_initial.rb +100 -0
  294. data/sipper_test/test_strict_router_with_angled.rb +84 -0
  295. data/sipper_test/test_string_record.rb +31 -0
  296. data/sipper_test/test_subscribe_notify.rb +141 -0
  297. data/sipper_test/test_subscribe_notify_client_timeout.rb +158 -0
  298. data/sipper_test/test_subscribe_notify_dialog.rb +146 -0
  299. data/sipper_test/test_subscribe_notify_expires.rb +155 -0
  300. data/sipper_test/test_subscribe_notify_multiple_subscription.rb +157 -0
  301. data/sipper_test/test_subscribe_notify_server_timeout.rb +144 -0
  302. data/sipper_test/test_subsequent_unsent.rb +88 -0
  303. data/sipper_test/test_target_refresh_proxy_detached.rb +128 -0
  304. data/sipper_test/test_target_refresh_proxy_udp.rb +130 -0
  305. data/sipper_test/test_target_refresh_rr_proxy_udp.rb +133 -0
  306. data/sipper_test/test_target_refresh_with_new_port.rb +158 -0
  307. data/sipper_test/test_target_refresh_with_proxy1.rb +113 -0
  308. data/sipper_test/test_target_refresh_with_rr_update_proxy.rb +145 -0
  309. data/sipper_test/test_target_refresh_with_update_proxy.rb +144 -0
  310. data/sipper_test/test_target_refresh_with_update_proxy2.rb +139 -0
  311. data/sipper_test/test_timer_manager.rb +71 -0
  312. data/sipper_test/test_timer_task.rb +60 -0
  313. data/sipper_test/test_transport_handler.rb +19 -0
  314. data/sipper_test/test_transport_multi_handler.rb +18 -0
  315. data/sipper_test/test_udp_transport.rb +119 -0
  316. data/sipper_test/test_unparsed.rb +70 -0
  317. data/sipper_test/test_validations.rb +69 -0
  318. data/sipper_test/test_with_rr_proxy.rb +111 -0
  319. data/sipper_test/testmediacontroller.rb +71 -0
  320. data/sipper_test/tracing.rb +23 -0
  321. data/sipper_test/transaction_test_helper.rb +176 -0
  322. data/sipper_test/transport_filters.rb +26 -0
  323. data/sipper_test/ts_sipper.rb +91 -0
  324. data/sipper_test/ts_smoke.rb +3 -0
  325. data/sipper_test/tt.cmd +20 -0
  326. metadata +455 -0
@@ -0,0 +1,33 @@
1
+ require 'transport/udp_transport'
2
+
3
+ class TransportManager
4
+
5
+ attr_reader :transports
6
+
7
+ def initialize
8
+ @transports = []
9
+ end
10
+
11
+ def add_transport tp
12
+ @transports << tp
13
+ end
14
+
15
+ #["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]
16
+ def get_transport_for(transport_info)
17
+ @transports[0] #todo have the MH logic here
18
+ end
19
+
20
+ # todo find a way to return a different
21
+ # this return transport suitable for sending to ip / port
22
+ def get_udp_transport_for(ip, port)
23
+ @transports[0]
24
+ end
25
+
26
+ # This returns a transport that matches the ip and port as given
27
+ def get_udp_transport_with(ip, port)
28
+ @transports.each do |tr|
29
+ return tr if (tr.ip == ip && tr.port == port)
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,17 @@
1
+ require 'session'
2
+ require 'sip_logger'
3
+
4
+ class UdpSession < Session
5
+ include SipLogger
6
+
7
+ def initialize(rip, rp, rs, session_limit=nil, specified_transport = nil)
8
+ if specified_transport
9
+ tp = SIP::Locator[:Tm].get_udp_transport_with(specified_transport[0], specified_transport[1])
10
+ else
11
+ tp = SIP::Locator[:Tm].get_udp_transport_for(rip, rp) if rip && rp
12
+ end
13
+
14
+ super(tp, rip, rp, rs, session_limit)
15
+ end
16
+
17
+ end
@@ -0,0 +1,62 @@
1
+ # This is a generator helper class addding some commad level fucntionality in the generated
2
+ # code from the generate module.
3
+
4
+ require 'sip_logger'
5
+ require 'strscan'
6
+ require 'util/sipper_util'
7
+ require 'ruby_ext/string'
8
+ require 'ruby_ext/object'
9
+
10
+ require 'facets/core/string/first_char'
11
+
12
+ module SipperUtil
13
+
14
+ # One command element is like "@sleep 500" where the requirement is to add a sleep element for 500ms
15
+ # in the genarted code.
16
+ # Since a CommandElement is used alongside the ExpectationElement we have a direction attribute
17
+ # returning "@" sign.
18
+ # There is no space after @ sign for commands. The commands are methods defined on this class.
19
+
20
+ class CommandElement
21
+
22
+ include SipLogger
23
+ include SipperUtil
24
+
25
+ # Command id is a general purpose id which can be used to identify/differentiate
26
+ # commands.
27
+ attr_reader :command_str, :command, :command_id, :direction
28
+
29
+ @@id_counter = 0
30
+
31
+ def initialize(str)
32
+ s = StringScanner.new(str)
33
+ m = nil
34
+ @direction = s.getch
35
+ log_and_raise "Improper direction in cmd str", ArgumentError unless @direction == "@"
36
+ m = s.scan_until(/$/)
37
+ @command, *args = m.split
38
+ log_and_raise "Bad command str, no command", ArgumentError unless @command
39
+ @command_id = "id" + String(@@id_counter+=1)
40
+ @command_str = self.send @command.to_sym, *args
41
+ end
42
+
43
+ # The command to make the flow sleep for specified amount of milliseconds.
44
+ # e.g. "@sleep_ms 500"
45
+ def sleep_ms(ms)
46
+ flt_ms = Float(ms)
47
+ log_and_raise "Negative argument is not allowed", ArgumentError if flt_ms < 0
48
+ "sleep #{flt_ms/1000.0}"
49
+ end
50
+
51
+ # Command to set a timer for this time, on expiration of this timer the next command or
52
+ # action is taken.
53
+ def set_timer(ms)
54
+ flt_ms = Float(ms)
55
+ log_and_raise "Negative argument is not allowed", ArgumentError if flt_ms < 0
56
+ "session.schedule_timer_for(\"#{@command_id}\", #{flt_ms})"
57
+ end
58
+
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,50 @@
1
+ require 'facets/core/hash/inverse'
2
+ require 'util/sipper_util'
3
+
4
+ module SipperUtil
5
+
6
+ class CompactConverter
7
+ # Ref : http://www.iana.org/assignments/sip-parameters
8
+ COMP_TO_EXPANDED = {
9
+ "a" => "accept_contact",
10
+ "u" => "allow_events",
11
+ "i" => "call_id",
12
+ "m" => "contact",
13
+ "e" => "content_encoding",
14
+ "l" => "content_length",
15
+ "c" => "content_type",
16
+ "o" => "event",
17
+ "f" => "from",
18
+ "y" => "identity",
19
+ "n" => "identity_info",
20
+ "r" => "refer_to",
21
+ "b" => "referred_by",
22
+ "j" => "reject_contact",
23
+ "d" => "request_disposition",
24
+ "x" => "session_expires",
25
+ "s" => "subject",
26
+ "k" => "supported",
27
+ "t" => "to",
28
+ "v" => "via"
29
+ }
30
+
31
+ EXPANDED_TO_COMP = COMP_TO_EXPANDED.invert
32
+
33
+ def self.get_compact(ex_hdr)
34
+ EXPANDED_TO_COMP[SipperUtil.methodize(ex_hdr.to_s)]
35
+ end
36
+
37
+ def self.get_expanded(c_hdr)
38
+ SipperUtil.headerize(COMP_TO_EXPANDED[c_hdr.to_s.downcase])
39
+ end
40
+
41
+ def self.has_compact_form?(ex_hdr)
42
+ EXPANDED_TO_COMP.has_key?(SipperUtil.methodize(ex_hdr.to_s))
43
+ end
44
+
45
+ def self.has_expanded_form?(c_hdr)
46
+ COMP_TO_EXPANDED.has_key?(c_hdr.to_s.downcase)
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ require 'monitor'
2
+ require 'singleton'
3
+
4
+ module SipperUtil
5
+ class Counter
6
+ include Singleton
7
+
8
+ def initialize
9
+ @@class_lock = Monitor.new
10
+ @@counter = 0
11
+ end
12
+
13
+ def next
14
+ @@class_lock.synchronize do
15
+ @@counter += 1
16
+ end
17
+ end
18
+
19
+ def reset
20
+ @@class_lock.synchronize do
21
+ @@counter = 0
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,204 @@
1
+ require 'util/sipper_util'
2
+ require 'digest/md5'
3
+ require 'base64'
4
+ require 'sipper_configurator'
5
+ require 'sip_headers/header'
6
+
7
+
8
+ # Digest authorizer is a stateful entity that maintains the state from previous challenges and
9
+ # calculates the digest according to RFC.
10
+ module SipperUtil
11
+ class DigestAuthorizer
12
+
13
+ attr_writer :salt
14
+
15
+ def initialize(salt=nil)
16
+ @same_challenge = true
17
+ @salt = salt || SipperConfigurator[:DigestSalt] || "sipper_rocks"
18
+ @nonce_count_table = {}
19
+ end
20
+
21
+ # Generated by UAC to respond to the challenge
22
+ def create_authorization_header(c, proxy, u, p, lsr)
23
+ @same_challenge = (@c.nonce == c.nonce) if @c
24
+ @c = c
25
+ @u = u
26
+ @p = p
27
+ @lsr = lsr
28
+ @cnonce = create_nonce
29
+ if @nonce_count_table[@c.nonce]
30
+ @nonce_count_table[@c.nonce] += 1
31
+ else
32
+ @nonce_count_table[@c.nonce] = 1
33
+ end
34
+ if proxy
35
+ atn_hdr = SipHeaders::ProxyAuthorization.new
36
+ else
37
+ atn_hdr = SipHeaders::Authorization.new
38
+ end
39
+ atn_hdr.scheme = @c.scheme
40
+ atn_hdr.username = quote_str @u
41
+ atn_hdr.realm = @c.realm
42
+ atn_hdr.nonce = @c.nonce
43
+ atn_hdr.uri = quote_str @lsr.uri.to_s
44
+ atn_hdr.nc = nonce_count()
45
+ atn_hdr.opaque = @c.opaque
46
+ atn_hdr.algorithm = @c.algorithm
47
+ atn_hdr.qop = @c.qop
48
+ atn_hdr.cnonce = quote_str @cnonce
49
+ atn_hdr.response = quote_str digest_response()
50
+ return atn_hdr
51
+ end
52
+
53
+
54
+ private
55
+
56
+ def concat(*args)
57
+ args.join ':'
58
+ end
59
+
60
+ # Calculate H() as specified, this is just a simple hash.
61
+ # RFC 2617 : For the "MD5" and "MD5-sess" algorithms
62
+ # H(data) = MD5(data)
63
+ def h(data)
64
+ Digest::MD5.hexdigest data
65
+ end
66
+
67
+
68
+ # RFC 2617 : KD(secret, data) = H(concat(secret, ":", data)
69
+ def kd(secret, data)
70
+ h concat(secret, data)
71
+ end
72
+
73
+
74
+ def user_string
75
+ concat(@u, unquote_str(@c.realm), @p)
76
+ end
77
+
78
+
79
+ # A1
80
+ # RFC 2617 3.2.2.2 A1
81
+
82
+ # If the "algorithm" directive's value is "MD5" or is unspecified, then
83
+ # A1 is:
84
+ #
85
+ # A1 = unq(username-value) ":" unq(realm-value) ":" passwd
86
+ # where
87
+ # passwd = < user's password >
88
+ #
89
+ # If the "algorithm" directive's value is "MD5-sess", then A1 is
90
+ # calculated only once - on the first request by the client following
91
+ # receipt of a WWW-Authenticate challenge from the server. It uses the
92
+ # server nonce from that challenge, and the first client nonce value to
93
+ # construct A1 as follows:
94
+ #
95
+ # A1 = H( unq(username-value) ":" unq(realm-value)
96
+ # ":" passwd )
97
+ # ":" unq(nonce-value) ":" unq(cnonce-value)
98
+ #
99
+ # This creates a 'session key' for the authentication of subsequent
100
+ # requests and responses which is different for each "authentication
101
+ # session", thus limiting the amount of material hashed with any one
102
+ # key.
103
+ def a1
104
+ if @c.algorithm == 'MD5-sess'
105
+ if @same_challenge
106
+ @a1_sess = concat(h(user_string), unquote_str(@c.nonce), unquote_str(@cnonce)) unless @a1_sess
107
+ @a1_sess
108
+ else
109
+ @a1_sess = concat(h(user_string), unquote_str(@c.nonce), unquote_str(@cnonce))
110
+ end
111
+ else
112
+ user_string
113
+ end
114
+
115
+ end
116
+
117
+ # 3.2.2.3 A2
118
+
119
+ # If the "qop" directive's value is "auth" or is unspecified, then A2
120
+ # is:
121
+ #
122
+ # A2 = Method ":" digest-uri-value
123
+ # If the "qop" value is "auth-int", then A2 is:
124
+ #
125
+ # A2 = Method ":" digest-uri-value ":" H(entity-body)
126
+ #
127
+ # From 3261
128
+ # As a clarification to the calculation of the A2 value for
129
+ # message integrity assurance in the Digest authentication
130
+ # scheme, implementers should assume, when the entity-body is
131
+ # empty (that is, when SIP messages have no body) that the hash
132
+ # of the entity-body resolves to the MD5 hash of an empty
133
+ # string, or:
134
+ # H(entity-body) = MD5("") =
135
+ # "d41d8cd98f00b204e9800998ecf8427e"
136
+ def a2
137
+ if @c.qop && @c.qop == 'auth-int'
138
+ concat(@lsr.method, @lsr.uri.to_s, h(b=@lsr.body ? b : ""))
139
+ else
140
+ concat(@lsr.method, @lsr.uri.to_s)
141
+ end
142
+ end
143
+
144
+
145
+
146
+ # If the "qop" value is "auth" or "auth-int":
147
+ # request-digest = <"> < KD ( H(A1), unq(nonce-value)
148
+ # ":" nc-value
149
+ # ":" unq(cnonce-value)
150
+ # ":" unq(qop-value)
151
+ # ":" H(A2)
152
+ # ) <">
153
+ # If the "qop" directive is not present (this construction is for
154
+ # compatibility with RFC 2069):
155
+ # request-digest =
156
+ # <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) >
157
+ # <">
158
+ def digest_response
159
+ if @c.qop.nil?
160
+ kd(h(a1), concat(unquote_str(@c.nonce), h(a2)))
161
+ else
162
+ kd(h(a1), concat(unquote_str(@c.nonce),
163
+ nonce_count(),
164
+ unquote_str(@cnonce), unquote_str(@c.qop), h(a2)))
165
+ end
166
+ end
167
+
168
+
169
+ def create_nonce
170
+ now = Time.now
171
+ time = now.strftime("%Y-%m-%d %H:%M:%S").to_s + ':' + now.usec.to_s
172
+ Base64.encode64(
173
+ concat(time, h(concat(time, @salt)))
174
+ ).gsub("\n", '')[0..-3]
175
+ end
176
+
177
+ def create_opaque
178
+ s = []; 16.times { s << rand(127).chr }
179
+ h s.join
180
+ end
181
+
182
+
183
+
184
+ def nonce_count
185
+ (@nonce_count_table[@c.nonce]).to_s(16).rjust 8, '0'
186
+ end
187
+
188
+ def quote_str(str)
189
+ qs = '"'
190
+ qs << str << '"'
191
+ qs
192
+ end
193
+
194
+ def unquote_str(str)
195
+ if str[0].chr == '"'
196
+ str[1...-1]
197
+ else
198
+ str
199
+ end
200
+ end
201
+
202
+ end # class
203
+
204
+ end # module
@@ -0,0 +1,164 @@
1
+
2
+ # 1. Wilcard for responses only 2xx, 1xx, 18x etc for responses
3
+ # 2. Alteration "< INVITE|SUBSCRIBE" optional request
4
+ # 3. Repetition "> INVITE {2,2}" have exactly 2. "< 18x {2,3}" have 2 or 3. "> 18x {,3}" at most 3"
5
+ # "> INVITE {0,}" variable. "< BYE {1,} at least 1.
6
+ # 4. For wildcard responses the first character in the message MUST be a number like 1xx is valid as
7
+ # is 41x but xxx or x00 is not valid. Character 'x' is used a wildcard.
8
+ # 5. The neutral expectation, the one recorded by the controller is recorded with the direction element
9
+ # "!" and the string should not contain any spaces.
10
+ # An element is satisfied if the minimum requirement is met for that.
11
+ # BNF Grammar is "DIRECTION MSGEXPRESSION|MSGEXPREESION REPETITION"
12
+
13
+ require 'sip_logger'
14
+ require 'strscan'
15
+ require 'util/sipper_util'
16
+ require 'ruby_ext/string'
17
+ require 'ruby_ext/object'
18
+
19
+ require 'facets/core/string/first_char'
20
+
21
+ module SipperUtil
22
+
23
+ # one expectation element is like "< INVITE {1,2}" or "> 1xx {0,}"
24
+ class ExpectationElement
25
+
26
+ include SipLogger
27
+ include SipperUtil
28
+
29
+ Directions = ["<", ">", "!", "@"]
30
+ MAX_REPEAT = 10000
31
+
32
+ attr_accessor :messages, :direction, :range, :satisfied
33
+
34
+ def initialize(str)
35
+ s = StringScanner.new(str)
36
+ m = nil
37
+ @direction = s.getch
38
+ log_and_raise "Improper direction in exp str", ArgumentError unless Directions.include?(@direction)
39
+ log_and_raise "Bad exp str, no space", ArgumentError unless s.scan(/\s+/) # space
40
+ if s.exist?(/\s+/)
41
+ m = s.scan_until(/\s+/).strip
42
+ else
43
+ m = s.scan_until(/$/)
44
+ end
45
+ @messages = m.split("|")
46
+ log_and_raise "Bad exp str, no message", ArgumentError unless @messages
47
+ # Enforce that wildcard is used rather than a check for say 200|202 etc for responses
48
+ if @messages[0] =~ /^\d/ && @messages.length>0
49
+ 1.upto @messages.length-1 do |n|
50
+ log_and_raise "Bad exp str, use wildcard instead of |", ArgumentError if @messages[0][0] == @messages[n][0]
51
+ end
52
+ end
53
+ if s.eos?
54
+ @range = Range.new(1,1)
55
+ else
56
+ rep = s.scan_until(/$/)
57
+ log_and_raise "Bad repetition in exp str", ArgumentError unless(rep.first_char(1)=="{" && rep.last_char(1)=="}")
58
+ rep_str = rep[1...-1]
59
+ min, max = rep_str.split(",")
60
+ min = 0 unless (min && min.size>0)
61
+ max = MAX_REPEAT unless (max && max.size>0)
62
+ min = Integer(min)
63
+ max = Integer(max)
64
+ @range = Range.new(min, max)
65
+ end
66
+ @satisfied = false
67
+ end
68
+
69
+ end
70
+
71
+
72
+
73
+ class ExpectationParser
74
+ # expectations
75
+ attr_accessor :exps
76
+
77
+ def parse(ex_ary)
78
+ @exps = []
79
+ ex_ary.each {|str| @exps << ExpectationElement.new(str) }
80
+ @idx = 0
81
+ @match_count = 0
82
+ end
83
+
84
+ # input string is "> INVITE" or "< 100" etc.
85
+ def match(str)
86
+ d, m = str.split(" ")
87
+ _match(d, m)
88
+ end
89
+
90
+ # A recorded message will have a direction and message itself.
91
+ def _match(dir, message)
92
+ return [false, nil] if @idx >= @exps.length
93
+ matched = true
94
+ matched = false if dir != @exps[@idx].direction
95
+ if matched
96
+ if dir == ::SipperUtil::ExpectationElement::Directions[2] # "!"
97
+ matched = _match_neutral(message)
98
+ elsif message.first_char(1).int?
99
+ matched = _match_response(message)
100
+ else
101
+ matched = _match_request(message)
102
+ end
103
+ end
104
+ if matched
105
+ @match_count += 1
106
+ return [true, nil] if @match_count < @exps[@idx].range.min
107
+ return [false,_unmatched_expectation] if @match_count > @exps[@idx].range.max
108
+ if @exps[@idx].range.include? @match_count
109
+ @exps[@idx].satisfied = true
110
+ return [true, nil]
111
+ end
112
+ else
113
+ if (@exps[@idx].satisfied || @exps[@idx].range.min == 0)
114
+ @idx += 1
115
+ @match_count = 0
116
+ return _match(dir, message) # match next
117
+ else
118
+ return [false,_unmatched_expectation]
119
+ end
120
+ end
121
+ end
122
+
123
+ def _match_response(res)
124
+ return false if res.length != 3
125
+ matched = true
126
+ @exps[@idx].messages.each do |m|
127
+ return false unless m.first_char(1).int?
128
+ matched = true
129
+ 0.upto(2) do |n|
130
+ unless m[n,1]=="x"
131
+ if m[n] != res[n]
132
+ matched = false
133
+ break
134
+ end
135
+ end
136
+ end
137
+ return true if matched
138
+ end
139
+ return matched
140
+ end
141
+
142
+ def _match_request(req)
143
+ @exps[@idx].messages.each do |m|
144
+ return true if m == req
145
+ end
146
+ return false
147
+ end
148
+
149
+ def _match_neutral(txt)
150
+ @exps[@idx].messages.each do |m|
151
+ return true if m == txt
152
+ end
153
+ return false
154
+ end
155
+
156
+ def _unmatched_expectation
157
+ "#{@exps[@idx].direction} #{@exps[@idx].messages.join(' or ')} between #{@exps[@idx].range.min} and #{@exps[@idx].range.max}"
158
+ end
159
+
160
+ private :_unmatched_expectation, :_match_response, :_match_request, :_match
161
+
162
+ end
163
+
164
+ end