rbczmq 1.6.2 → 1.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (398) hide show
  1. data/.gitignore +4 -3
  2. data/.gitmodules +6 -0
  3. data/.travis.yml +5 -1
  4. data/CHANGELOG.rdoc +15 -0
  5. data/Gemfile.lock +2 -2
  6. data/README.rdoc +5 -2
  7. data/Rakefile +8 -3
  8. data/ext/czmq/.gitignore +52 -0
  9. data/ext/czmq/.travis.yml +18 -0
  10. data/ext/czmq/AUTHORS +9 -0
  11. data/ext/czmq/COPYING +674 -0
  12. data/ext/czmq/COPYING.LESSER +178 -0
  13. data/ext/czmq/ChangeLog +0 -0
  14. data/ext/czmq/Makefile.am +22 -0
  15. data/ext/czmq/NEWS +263 -0
  16. data/ext/czmq/README +0 -0
  17. data/ext/czmq/README.md +1122 -0
  18. data/ext/czmq/README.txt +327 -0
  19. data/ext/czmq/autogen.sh +46 -0
  20. data/ext/czmq/builds/android/Android.mk +35 -0
  21. data/ext/czmq/builds/android/Application.mk +1 -0
  22. data/ext/czmq/builds/android/build.sh +59 -0
  23. data/ext/czmq/builds/android/clean.sh +26 -0
  24. data/ext/czmq/builds/mingw32/Makefile.mingw32 +38 -0
  25. data/ext/czmq/builds/mingw32/platform.h +0 -0
  26. data/ext/czmq/builds/msvc/.gitignore +18 -0
  27. data/ext/czmq/builds/msvc/README.txt +17 -0
  28. data/ext/czmq/builds/msvc/czmq.sln +69 -0
  29. data/ext/czmq/builds/msvc/czmq.vcproj +2246 -0
  30. data/ext/czmq/builds/msvc/czmq.vcxproj +329 -0
  31. data/ext/czmq/builds/msvc/czmq.vcxproj.filters +117 -0
  32. data/ext/czmq/builds/msvc/czmq11.sln +36 -0
  33. data/ext/czmq/builds/msvc/czmq_selftest.vcproj +840 -0
  34. data/ext/czmq/builds/msvc/czmq_selftest.vcxproj +189 -0
  35. data/ext/czmq/builds/msvc/czmq_selftest.vcxproj.filters +14 -0
  36. data/ext/czmq/c +520 -0
  37. data/ext/czmq/configure.ac +229 -0
  38. data/ext/czmq/doc/Makefile.am +49 -0
  39. data/ext/czmq/doc/asciidoc.conf +57 -0
  40. data/ext/czmq/doc/czmq.txt +334 -0
  41. data/ext/czmq/doc/mkman +100 -0
  42. data/ext/czmq/doc/mksite +65 -0
  43. data/ext/czmq/doc/wdput +43 -0
  44. data/ext/czmq/doc/xml2wd.pl +242 -0
  45. data/ext/czmq/doc/zbeacon.txt +173 -0
  46. data/ext/czmq/doc/zclock.txt +51 -0
  47. data/ext/czmq/doc/zconfig.txt +92 -0
  48. data/ext/czmq/doc/zctx.txt +111 -0
  49. data/ext/czmq/doc/zfile.txt +77 -0
  50. data/ext/czmq/doc/zframe.txt +222 -0
  51. data/ext/czmq/doc/zhash.txt +225 -0
  52. data/ext/czmq/doc/zlist.txt +176 -0
  53. data/ext/czmq/doc/zloop.txt +106 -0
  54. data/ext/czmq/doc/zmsg.txt +315 -0
  55. data/ext/czmq/doc/zmutex.txt +54 -0
  56. data/ext/czmq/doc/zsocket.txt +110 -0
  57. data/ext/czmq/doc/zsockopt.txt +528 -0
  58. data/ext/czmq/doc/zstr.txt +80 -0
  59. data/ext/czmq/doc/zsys.txt +44 -0
  60. data/ext/czmq/doc/zthread.txt +126 -0
  61. data/ext/czmq/doc/ztree.txt +236 -0
  62. data/ext/czmq/images/README_1.png +0 -0
  63. data/ext/czmq/images/README_2.png +0 -0
  64. data/ext/czmq/include/czmq.h +64 -0
  65. data/ext/czmq/include/czmq_prelude.h +504 -0
  66. data/ext/czmq/include/zbeacon.h +91 -0
  67. data/ext/czmq/include/zclock.h +56 -0
  68. data/ext/czmq/include/zconfig.h +117 -0
  69. data/ext/czmq/include/zctx.h +96 -0
  70. data/ext/czmq/include/zfile.h +82 -0
  71. data/ext/czmq/include/zframe.h +145 -0
  72. data/ext/czmq/include/zhash.h +127 -0
  73. data/ext/czmq/include/zlist.h +113 -0
  74. data/ext/czmq/include/zloop.h +98 -0
  75. data/ext/czmq/include/zmsg.h +165 -0
  76. data/ext/czmq/include/zmutex.h +62 -0
  77. data/ext/czmq/include/zsocket.h +104 -0
  78. data/ext/czmq/include/zsockopt.h +249 -0
  79. data/ext/czmq/include/zstr.h +69 -0
  80. data/ext/czmq/include/zsys.h +66 -0
  81. data/ext/czmq/include/zthread.h +62 -0
  82. data/ext/czmq/include/ztree.h +133 -0
  83. data/ext/czmq/mkdoc +14 -0
  84. data/ext/czmq/model/generate +2 -0
  85. data/ext/czmq/model/sockopts.xml +101 -0
  86. data/ext/czmq/notes.txt +21 -0
  87. data/ext/czmq/scripts/sockopts.gsl +325 -0
  88. data/ext/czmq/src/Makefile.am +61 -0
  89. data/ext/czmq/src/czmq_selftest.c +60 -0
  90. data/ext/czmq/src/libczmq.pc.in +11 -0
  91. data/ext/czmq/src/selftest +7 -0
  92. data/ext/czmq/src/selftest.cfg +5 -0
  93. data/ext/czmq/src/valgrind.supp +14 -0
  94. data/ext/czmq/src/vg +2 -0
  95. data/ext/czmq/src/zbeacon.c +787 -0
  96. data/ext/czmq/src/zclock.c +143 -0
  97. data/ext/czmq/src/zconfig.c +691 -0
  98. data/ext/czmq/src/zctx.c +287 -0
  99. data/ext/czmq/src/zfile.c +237 -0
  100. data/ext/czmq/src/zframe.c +551 -0
  101. data/ext/czmq/src/zhash.c +664 -0
  102. data/ext/czmq/src/zlist.c +459 -0
  103. data/ext/czmq/src/zloop.c +496 -0
  104. data/ext/czmq/src/zmsg.c +854 -0
  105. data/ext/czmq/src/zmutex.c +134 -0
  106. data/ext/czmq/src/zsocket.c +313 -0
  107. data/ext/czmq/src/zsockopt.c +1756 -0
  108. data/ext/czmq/src/zstr.c +297 -0
  109. data/ext/czmq/src/zsys.c +136 -0
  110. data/ext/czmq/src/zthread.c +269 -0
  111. data/ext/czmq/src/ztree.c +888 -0
  112. data/ext/czmq/version.sh +21 -0
  113. data/ext/rbczmq/extconf.rb +1 -18
  114. data/ext/rbczmq/poller.c +4 -1
  115. data/ext/rbczmq/socket.c +28 -5
  116. data/ext/rbczmq/socket.h +1 -0
  117. data/ext/zeromq/AUTHORS +110 -0
  118. data/ext/zeromq/CMakeLists.txt +392 -0
  119. data/ext/zeromq/COPYING +674 -0
  120. data/ext/zeromq/COPYING.LESSER +179 -0
  121. data/ext/zeromq/INSTALL +246 -0
  122. data/ext/zeromq/MAINTAINERS +56 -0
  123. data/ext/zeromq/Makefile.am +40 -0
  124. data/ext/zeromq/NEWS +333 -0
  125. data/ext/zeromq/README +39 -0
  126. data/ext/zeromq/acinclude.m4 +930 -0
  127. data/ext/zeromq/autogen.sh +45 -0
  128. data/ext/zeromq/branding.bmp +0 -0
  129. data/ext/zeromq/builds/msvc/Makefile.am +33 -0
  130. data/ext/zeromq/builds/msvc/c_local_lat/c_local_lat.vcproj +176 -0
  131. data/ext/zeromq/builds/msvc/c_local_lat/c_local_lat.vcxproj +87 -0
  132. data/ext/zeromq/builds/msvc/c_local_thr/c_local_thr.vcproj +176 -0
  133. data/ext/zeromq/builds/msvc/c_local_thr/c_local_thr.vcxproj +87 -0
  134. data/ext/zeromq/builds/msvc/c_remote_lat/c_remote_lat.vcproj +176 -0
  135. data/ext/zeromq/builds/msvc/c_remote_lat/c_remote_lat.vcxproj +87 -0
  136. data/ext/zeromq/builds/msvc/c_remote_thr/c_remote_thr.vcproj +176 -0
  137. data/ext/zeromq/builds/msvc/c_remote_thr/c_remote_thr.vcxproj +87 -0
  138. data/ext/zeromq/builds/msvc/errno.cpp +32 -0
  139. data/ext/zeromq/builds/msvc/errno.hpp +56 -0
  140. data/ext/zeromq/builds/msvc/inproc_lat/inproc_lat.vcproj +174 -0
  141. data/ext/zeromq/builds/msvc/inproc_lat/inproc_lat.vcxproj +86 -0
  142. data/ext/zeromq/builds/msvc/inproc_thr/inproc_thr.vcproj +174 -0
  143. data/ext/zeromq/builds/msvc/inproc_thr/inproc_thr.vcxproj +86 -0
  144. data/ext/zeromq/builds/msvc/libzmq/libzmq.vcproj +804 -0
  145. data/ext/zeromq/builds/msvc/libzmq/libzmq.vcxproj +252 -0
  146. data/ext/zeromq/builds/msvc/libzmq/libzmq.vcxproj.filters +431 -0
  147. data/ext/zeromq/builds/msvc/msvc.sln +89 -0
  148. data/ext/zeromq/builds/msvc/msvc10.sln +116 -0
  149. data/ext/zeromq/builds/msvc/platform.hpp +32 -0
  150. data/ext/zeromq/builds/msvc/properties/Common.props +21 -0
  151. data/ext/zeromq/builds/msvc/properties/Debug.props +19 -0
  152. data/ext/zeromq/builds/msvc/properties/Dynamic.props +20 -0
  153. data/ext/zeromq/builds/msvc/properties/Executable.props +19 -0
  154. data/ext/zeromq/builds/msvc/properties/Precompiled.props +14 -0
  155. data/ext/zeromq/builds/msvc/properties/Release.props +22 -0
  156. data/ext/zeromq/builds/msvc/properties/Win32.props +12 -0
  157. data/ext/zeromq/builds/msvc/properties/Win32_Release.props +17 -0
  158. data/ext/zeromq/builds/msvc/properties/WithOpenPGM.props +12 -0
  159. data/ext/zeromq/builds/msvc/properties/ZeroMQ.props +23 -0
  160. data/ext/zeromq/builds/msvc/properties/x64.props +12 -0
  161. data/ext/zeromq/builds/redhat/zeromq.spec.in +160 -0
  162. data/ext/zeromq/builds/valgrind/valgrind.supp +14 -0
  163. data/ext/zeromq/builds/valgrind/vg +1 -0
  164. data/ext/zeromq/cmake/Modules/TestZMQVersion.cmake +35 -0
  165. data/ext/zeromq/cmake/Modules/zmq_version.cpp +31 -0
  166. data/ext/zeromq/cmake/NSIS.template32.in +952 -0
  167. data/ext/zeromq/cmake/NSIS.template64.in +960 -0
  168. data/ext/zeromq/configure.in +428 -0
  169. data/ext/zeromq/doc/Makefile.am +51 -0
  170. data/ext/zeromq/doc/asciidoc.conf +56 -0
  171. data/ext/zeromq/doc/zmq.txt +233 -0
  172. data/ext/zeromq/doc/zmq_bind.txt +102 -0
  173. data/ext/zeromq/doc/zmq_close.txt +52 -0
  174. data/ext/zeromq/doc/zmq_connect.txt +98 -0
  175. data/ext/zeromq/doc/zmq_ctx_destroy.txt +66 -0
  176. data/ext/zeromq/doc/zmq_ctx_get.txt +67 -0
  177. data/ext/zeromq/doc/zmq_ctx_new.txt +49 -0
  178. data/ext/zeromq/doc/zmq_ctx_set.txt +75 -0
  179. data/ext/zeromq/doc/zmq_disconnect.txt +67 -0
  180. data/ext/zeromq/doc/zmq_epgm.txt +162 -0
  181. data/ext/zeromq/doc/zmq_errno.txt +50 -0
  182. data/ext/zeromq/doc/zmq_getsockopt.txt +516 -0
  183. data/ext/zeromq/doc/zmq_init.txt +52 -0
  184. data/ext/zeromq/doc/zmq_inproc.txt +85 -0
  185. data/ext/zeromq/doc/zmq_ipc.txt +85 -0
  186. data/ext/zeromq/doc/zmq_msg_close.txt +55 -0
  187. data/ext/zeromq/doc/zmq_msg_copy.txt +57 -0
  188. data/ext/zeromq/doc/zmq_msg_data.txt +48 -0
  189. data/ext/zeromq/doc/zmq_msg_get.txt +72 -0
  190. data/ext/zeromq/doc/zmq_msg_init.txt +65 -0
  191. data/ext/zeromq/doc/zmq_msg_init_data.txt +85 -0
  192. data/ext/zeromq/doc/zmq_msg_init_size.txt +58 -0
  193. data/ext/zeromq/doc/zmq_msg_more.txt +63 -0
  194. data/ext/zeromq/doc/zmq_msg_move.txt +52 -0
  195. data/ext/zeromq/doc/zmq_msg_recv.txt +125 -0
  196. data/ext/zeromq/doc/zmq_msg_send.txt +122 -0
  197. data/ext/zeromq/doc/zmq_msg_set.txt +45 -0
  198. data/ext/zeromq/doc/zmq_msg_size.txt +48 -0
  199. data/ext/zeromq/doc/zmq_pgm.txt +162 -0
  200. data/ext/zeromq/doc/zmq_poll.txt +132 -0
  201. data/ext/zeromq/doc/zmq_proxy.txt +97 -0
  202. data/ext/zeromq/doc/zmq_recv.txt +93 -0
  203. data/ext/zeromq/doc/zmq_recvmsg.txt +123 -0
  204. data/ext/zeromq/doc/zmq_send.txt +100 -0
  205. data/ext/zeromq/doc/zmq_sendmsg.txt +119 -0
  206. data/ext/zeromq/doc/zmq_setsockopt.txt +523 -0
  207. data/ext/zeromq/doc/zmq_socket.txt +369 -0
  208. data/ext/zeromq/doc/zmq_socket_monitor.txt +288 -0
  209. data/ext/zeromq/doc/zmq_strerror.txt +55 -0
  210. data/ext/zeromq/doc/zmq_tcp.txt +101 -0
  211. data/ext/zeromq/doc/zmq_term.txt +66 -0
  212. data/ext/zeromq/doc/zmq_unbind.txt +65 -0
  213. data/ext/zeromq/doc/zmq_version.txt +53 -0
  214. data/ext/zeromq/foreign/openpgm/Makefile.am +8 -0
  215. data/ext/zeromq/foreign/openpgm/libpgm-5.1.118~dfsg.tar.gz +0 -0
  216. data/ext/zeromq/include/zmq.h +402 -0
  217. data/ext/zeromq/include/zmq_utils.h +64 -0
  218. data/ext/zeromq/installer.ico +0 -0
  219. data/ext/zeromq/perf/Makefile.am +22 -0
  220. data/ext/zeromq/perf/inproc_lat.cpp +233 -0
  221. data/ext/zeromq/perf/inproc_thr.cpp +241 -0
  222. data/ext/zeromq/perf/local_lat.cpp +109 -0
  223. data/ext/zeromq/perf/local_thr.cpp +133 -0
  224. data/ext/zeromq/perf/remote_lat.cpp +122 -0
  225. data/ext/zeromq/perf/remote_thr.cpp +105 -0
  226. data/ext/zeromq/src/Makefile.am +171 -0
  227. data/ext/zeromq/src/address.cpp +78 -0
  228. data/ext/zeromq/src/address.hpp +52 -0
  229. data/ext/zeromq/src/array.hpp +155 -0
  230. data/ext/zeromq/src/atomic_counter.hpp +197 -0
  231. data/ext/zeromq/src/atomic_ptr.hpp +196 -0
  232. data/ext/zeromq/src/blob.hpp +129 -0
  233. data/ext/zeromq/src/clock.cpp +147 -0
  234. data/ext/zeromq/src/clock.hpp +60 -0
  235. data/ext/zeromq/src/command.hpp +154 -0
  236. data/ext/zeromq/src/config.hpp +89 -0
  237. data/ext/zeromq/src/ctx.cpp +352 -0
  238. data/ext/zeromq/src/ctx.hpp +173 -0
  239. data/ext/zeromq/src/dealer.cpp +133 -0
  240. data/ext/zeromq/src/dealer.hpp +92 -0
  241. data/ext/zeromq/src/decoder.cpp +166 -0
  242. data/ext/zeromq/src/decoder.hpp +248 -0
  243. data/ext/zeromq/src/devpoll.cpp +190 -0
  244. data/ext/zeromq/src/devpoll.hpp +105 -0
  245. data/ext/zeromq/src/dist.cpp +194 -0
  246. data/ext/zeromq/src/dist.hpp +105 -0
  247. data/ext/zeromq/src/encoder.cpp +102 -0
  248. data/ext/zeromq/src/encoder.hpp +200 -0
  249. data/ext/zeromq/src/epoll.cpp +178 -0
  250. data/ext/zeromq/src/epoll.hpp +101 -0
  251. data/ext/zeromq/src/err.cpp +291 -0
  252. data/ext/zeromq/src/err.hpp +155 -0
  253. data/ext/zeromq/src/fd.hpp +45 -0
  254. data/ext/zeromq/src/fq.cpp +141 -0
  255. data/ext/zeromq/src/fq.hpp +74 -0
  256. data/ext/zeromq/src/i_decoder.hpp +49 -0
  257. data/ext/zeromq/src/i_encoder.hpp +55 -0
  258. data/ext/zeromq/src/i_engine.hpp +55 -0
  259. data/ext/zeromq/src/i_msg_sink.hpp +43 -0
  260. data/ext/zeromq/src/i_msg_source.hpp +44 -0
  261. data/ext/zeromq/src/i_poll_events.hpp +47 -0
  262. data/ext/zeromq/src/io_object.cpp +108 -0
  263. data/ext/zeromq/src/io_object.hpp +81 -0
  264. data/ext/zeromq/src/io_thread.cpp +104 -0
  265. data/ext/zeromq/src/io_thread.hpp +91 -0
  266. data/ext/zeromq/src/ip.cpp +109 -0
  267. data/ext/zeromq/src/ip.hpp +41 -0
  268. data/ext/zeromq/src/ipc_address.cpp +84 -0
  269. data/ext/zeromq/src/ipc_address.hpp +67 -0
  270. data/ext/zeromq/src/ipc_connecter.cpp +265 -0
  271. data/ext/zeromq/src/ipc_connecter.hpp +128 -0
  272. data/ext/zeromq/src/ipc_listener.cpp +206 -0
  273. data/ext/zeromq/src/ipc_listener.hpp +99 -0
  274. data/ext/zeromq/src/kqueue.cpp +201 -0
  275. data/ext/zeromq/src/kqueue.hpp +107 -0
  276. data/ext/zeromq/src/lb.cpp +148 -0
  277. data/ext/zeromq/src/lb.hpp +73 -0
  278. data/ext/zeromq/src/libzmq.pc.in +10 -0
  279. data/ext/zeromq/src/likely.hpp +33 -0
  280. data/ext/zeromq/src/mailbox.cpp +87 -0
  281. data/ext/zeromq/src/mailbox.hpp +75 -0
  282. data/ext/zeromq/src/msg.cpp +299 -0
  283. data/ext/zeromq/src/msg.hpp +148 -0
  284. data/ext/zeromq/src/mtrie.cpp +428 -0
  285. data/ext/zeromq/src/mtrie.hpp +93 -0
  286. data/ext/zeromq/src/mutex.hpp +118 -0
  287. data/ext/zeromq/src/object.cpp +393 -0
  288. data/ext/zeromq/src/object.hpp +134 -0
  289. data/ext/zeromq/src/options.cpp +562 -0
  290. data/ext/zeromq/src/options.hpp +135 -0
  291. data/ext/zeromq/src/own.cpp +206 -0
  292. data/ext/zeromq/src/own.hpp +145 -0
  293. data/ext/zeromq/src/pair.cpp +136 -0
  294. data/ext/zeromq/src/pair.hpp +79 -0
  295. data/ext/zeromq/src/pgm_receiver.cpp +283 -0
  296. data/ext/zeromq/src/pgm_receiver.hpp +141 -0
  297. data/ext/zeromq/src/pgm_sender.cpp +218 -0
  298. data/ext/zeromq/src/pgm_sender.hpp +113 -0
  299. data/ext/zeromq/src/pgm_socket.cpp +706 -0
  300. data/ext/zeromq/src/pgm_socket.hpp +124 -0
  301. data/ext/zeromq/src/pipe.cpp +447 -0
  302. data/ext/zeromq/src/pipe.hpp +207 -0
  303. data/ext/zeromq/src/poll.cpp +176 -0
  304. data/ext/zeromq/src/poll.hpp +105 -0
  305. data/ext/zeromq/src/poller.hpp +82 -0
  306. data/ext/zeromq/src/poller_base.cpp +99 -0
  307. data/ext/zeromq/src/poller_base.hpp +86 -0
  308. data/ext/zeromq/src/precompiled.cpp +21 -0
  309. data/ext/zeromq/src/precompiled.hpp +47 -0
  310. data/ext/zeromq/src/proxy.cpp +150 -0
  311. data/ext/zeromq/src/proxy.hpp +32 -0
  312. data/ext/zeromq/src/pub.cpp +57 -0
  313. data/ext/zeromq/src/pub.hpp +69 -0
  314. data/ext/zeromq/src/pull.cpp +79 -0
  315. data/ext/zeromq/src/pull.hpp +81 -0
  316. data/ext/zeromq/src/push.cpp +76 -0
  317. data/ext/zeromq/src/push.hpp +80 -0
  318. data/ext/zeromq/src/random.cpp +52 -0
  319. data/ext/zeromq/src/random.hpp +37 -0
  320. data/ext/zeromq/src/reaper.cpp +117 -0
  321. data/ext/zeromq/src/reaper.hpp +80 -0
  322. data/ext/zeromq/src/rep.cpp +137 -0
  323. data/ext/zeromq/src/rep.hpp +80 -0
  324. data/ext/zeromq/src/req.cpp +185 -0
  325. data/ext/zeromq/src/req.hpp +91 -0
  326. data/ext/zeromq/src/router.cpp +364 -0
  327. data/ext/zeromq/src/router.hpp +138 -0
  328. data/ext/zeromq/src/select.cpp +216 -0
  329. data/ext/zeromq/src/select.hpp +126 -0
  330. data/ext/zeromq/src/session_base.cpp +503 -0
  331. data/ext/zeromq/src/session_base.hpp +156 -0
  332. data/ext/zeromq/src/signaler.cpp +406 -0
  333. data/ext/zeromq/src/signaler.hpp +63 -0
  334. data/ext/zeromq/src/socket_base.cpp +1236 -0
  335. data/ext/zeromq/src/socket_base.hpp +255 -0
  336. data/ext/zeromq/src/stdint.hpp +63 -0
  337. data/ext/zeromq/src/stream_engine.cpp +594 -0
  338. data/ext/zeromq/src/stream_engine.hpp +149 -0
  339. data/ext/zeromq/src/sub.cpp +93 -0
  340. data/ext/zeromq/src/sub.hpp +71 -0
  341. data/ext/zeromq/src/tcp.cpp +131 -0
  342. data/ext/zeromq/src/tcp.hpp +38 -0
  343. data/ext/zeromq/src/tcp_address.cpp +613 -0
  344. data/ext/zeromq/src/tcp_address.hpp +100 -0
  345. data/ext/zeromq/src/tcp_connecter.cpp +319 -0
  346. data/ext/zeromq/src/tcp_connecter.hpp +123 -0
  347. data/ext/zeromq/src/tcp_listener.cpp +293 -0
  348. data/ext/zeromq/src/tcp_listener.hpp +91 -0
  349. data/ext/zeromq/src/thread.cpp +107 -0
  350. data/ext/zeromq/src/thread.hpp +79 -0
  351. data/ext/zeromq/src/trie.cpp +337 -0
  352. data/ext/zeromq/src/trie.hpp +79 -0
  353. data/ext/zeromq/src/v1_decoder.cpp +162 -0
  354. data/ext/zeromq/src/v1_decoder.hpp +68 -0
  355. data/ext/zeromq/src/v1_encoder.cpp +103 -0
  356. data/ext/zeromq/src/v1_encoder.hpp +60 -0
  357. data/ext/zeromq/src/v1_protocol.hpp +43 -0
  358. data/ext/zeromq/src/version.rc.in +93 -0
  359. data/ext/zeromq/src/windows.hpp +181 -0
  360. data/ext/zeromq/src/wire.hpp +99 -0
  361. data/ext/zeromq/src/xpub.cpp +200 -0
  362. data/ext/zeromq/src/xpub.hpp +110 -0
  363. data/ext/zeromq/src/xsub.cpp +242 -0
  364. data/ext/zeromq/src/xsub.hpp +108 -0
  365. data/ext/zeromq/src/ypipe.hpp +210 -0
  366. data/ext/zeromq/src/yqueue.hpp +199 -0
  367. data/ext/zeromq/src/zmq.cpp +1058 -0
  368. data/ext/zeromq/src/zmq_utils.cpp +61 -0
  369. data/ext/zeromq/tests/Makefile.am +55 -0
  370. data/ext/zeromq/tests/test_connect_delay.cpp +260 -0
  371. data/ext/zeromq/tests/test_connect_resolve.cpp +54 -0
  372. data/ext/zeromq/tests/test_disconnect_inproc.cpp +120 -0
  373. data/ext/zeromq/tests/test_hwm.cpp +83 -0
  374. data/ext/zeromq/tests/test_invalid_rep.cpp +92 -0
  375. data/ext/zeromq/tests/test_last_endpoint.cpp +60 -0
  376. data/ext/zeromq/tests/test_monitor.cpp +289 -0
  377. data/ext/zeromq/tests/test_msg_flags.cpp +78 -0
  378. data/ext/zeromq/tests/test_pair_inproc.cpp +53 -0
  379. data/ext/zeromq/tests/test_pair_ipc.cpp +53 -0
  380. data/ext/zeromq/tests/test_pair_tcp.cpp +54 -0
  381. data/ext/zeromq/tests/test_reqrep_device.cpp +143 -0
  382. data/ext/zeromq/tests/test_reqrep_inproc.cpp +53 -0
  383. data/ext/zeromq/tests/test_reqrep_ipc.cpp +53 -0
  384. data/ext/zeromq/tests/test_reqrep_tcp.cpp +54 -0
  385. data/ext/zeromq/tests/test_router_mandatory.cpp +62 -0
  386. data/ext/zeromq/tests/test_shutdown_stress.cpp +93 -0
  387. data/ext/zeromq/tests/test_sub_forward.cpp +99 -0
  388. data/ext/zeromq/tests/test_term_endpoint.cpp +118 -0
  389. data/ext/zeromq/tests/test_timeo.cpp +119 -0
  390. data/ext/zeromq/tests/testutil.hpp +77 -0
  391. data/ext/zeromq/version.sh +21 -0
  392. data/lib/zmq/version.rb +1 -1
  393. data/rbczmq.gemspec +16 -3
  394. data/test/test_socket.rb +13 -1
  395. metadata +398 -9
  396. checksums.yaml +0 -15
  397. data/ext/czmq-1.4.1.tar.gz +0 -0
  398. data/ext/zeromq-3.2.3.tar.gz +0 -0
@@ -0,0 +1,61 @@
1
+ lib_LTLIBRARIES = libczmq.la
2
+
3
+ pkgconfigdir = $(libdir)/pkgconfig
4
+ pkgconfig_DATA = libczmq.pc
5
+
6
+ include_HEADERS = \
7
+ ../include/czmq.h \
8
+ ../include/czmq_prelude.h \
9
+ ../include/zbeacon.h \
10
+ ../include/zclock.h \
11
+ ../include/zconfig.h \
12
+ ../include/zctx.h \
13
+ ../include/zfile.h \
14
+ ../include/zframe.h \
15
+ ../include/zhash.h \
16
+ ../include/zlist.h \
17
+ ../include/zloop.h \
18
+ ../include/zmsg.h \
19
+ ../include/zmutex.h \
20
+ ../include/zsocket.h \
21
+ ../include/zsockopt.h \
22
+ ../include/zstr.h \
23
+ ../include/zsys.h \
24
+ ../include/zthread.h \
25
+ ../include/ztree.h
26
+
27
+ libczmq_la_SOURCES = \
28
+ zbeacon.c \
29
+ zclock.c \
30
+ zconfig.c \
31
+ zctx.c \
32
+ zfile.c \
33
+ zframe.c \
34
+ zhash.c \
35
+ zlist.c \
36
+ zloop.c \
37
+ zmsg.c \
38
+ zmutex.c \
39
+ zsocket.c \
40
+ zsockopt.c \
41
+ zstr.c \
42
+ zsys.c \
43
+ zthread.c \
44
+ ztree.c
45
+
46
+ AM_CFLAGS = -g
47
+
48
+ INCLUDES = -I$(top_srcdir)/include
49
+ bin_PROGRAMS = czmq_selftest
50
+ czmq_selftest_LDADD = libczmq.la
51
+ czmq_selftest_SOURCES = czmq_selftest.c
52
+
53
+ if ON_MINGW
54
+ libczmq_la_LDFLAGS = -no-undefined -avoid-version -version-info @LTVER@
55
+ else
56
+ libczmq_la_LDFLAGS = -version-info @LTVER@
57
+ endif
58
+
59
+ TESTS = czmq_selftest
60
+
61
+
@@ -0,0 +1,60 @@
1
+ /* =========================================================================
2
+ czmq_tests.c - run selftests
3
+
4
+ Runs all selftests.
5
+
6
+ -------------------------------------------------------------------------
7
+ Copyright (c) 1991-2013 iMatix Corporation <www.imatix.com>
8
+ Copyright other contributors as noted in the AUTHORS file.
9
+
10
+ This file is part of czmq, the high-level C binding for 0MQ:
11
+ http://czmq.zeromq.org.
12
+
13
+ This is free software; you can redistribute it and/or modify it under
14
+ the terms of the GNU Lesser General Public License as published by
15
+ the Free Software Foundation; either version 3 of the License, or (at
16
+ your option) any later version.
17
+
18
+ This software is distributed in the hope that it will be useful, but
19
+ WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
+ Lesser General Public License for more details.
22
+
23
+ You should have received a copy of the GNU Lesser General Public
24
+ License along with this program. If not, see
25
+ <http://www.gnu.org/licenses/>.
26
+ =========================================================================
27
+ */
28
+
29
+ #include "../include/czmq.h"
30
+
31
+ int main (int argc, char *argv [])
32
+ {
33
+ bool verbose;
34
+ if (argc == 2 && streq (argv [1], "-v"))
35
+ verbose = true;
36
+ else
37
+ verbose = false;
38
+
39
+ printf ("Running czmq self tests...\n");
40
+
41
+ zclock_test (verbose);
42
+ zconfig_test (verbose);
43
+ zctx_test (verbose);
44
+ zfile_test (verbose);
45
+ zframe_test (verbose);
46
+ zhash_test (verbose);
47
+ ztree_test (verbose);
48
+ zlist_test (verbose);
49
+ zloop_test (verbose);
50
+ zmsg_test (verbose);
51
+ zmutex_test (verbose);
52
+ zsocket_test (verbose);
53
+ zsockopt_test (verbose);
54
+ zstr_test (verbose);
55
+ zsys_test (verbose);
56
+ zthread_test (verbose);
57
+ zbeacon_test (verbose);
58
+ printf ("Tests passed OK\n");
59
+ return 0;
60
+ }
@@ -0,0 +1,11 @@
1
+ prefix=@prefix@
2
+ exec_prefix=@exec_prefix@
3
+ libdir=@libdir@
4
+ includedir=@includedir@
5
+
6
+ Name: libczmq
7
+ Description: High-level C binding for 0MQ
8
+ Version: @VERSION@
9
+ Requires: libzmq
10
+ Libs: -L${libdir} -lczmq
11
+ Cflags: -I${includedir}
@@ -0,0 +1,7 @@
1
+ # Run selftests and check memory
2
+ echo "Rebuilding czmq..."
3
+ gcc -g -o czmq_selftest czmq_selftest.c z*.c ${CFLAGS} ${LDFLAGS} -lzmq -lpthread
4
+ if [ $? -eq 0 ]; then
5
+ echo "Starting Valgrind memcheck..."
6
+ valgrind --tool=memcheck --leak-check=full --suppressions=valgrind.supp ./czmq_selftest
7
+ fi
@@ -0,0 +1,5 @@
1
+ # ZPL config file used for self-tests
2
+ #
3
+ security
4
+ echo = I: server accepts anonymous access
5
+ anonymous = 1
@@ -0,0 +1,14 @@
1
+ {
2
+ <socketcall_sendto>
3
+ Memcheck:Param
4
+ socketcall.sendto(msg)
5
+ fun:send
6
+ ...
7
+ }
8
+ {
9
+ <socketcall_sendto>
10
+ Memcheck:Param
11
+ socketcall.send(msg)
12
+ fun:send
13
+ ...
14
+ }
@@ -0,0 +1,2 @@
1
+ c -l $1
2
+ valgrind --tool=memcheck --leak-check=full --suppressions=valgrind.supp $*
@@ -0,0 +1,787 @@
1
+ /* =========================================================================
2
+ zbeacon - LAN service announcement and discovery
3
+
4
+ -------------------------------------------------------------------------
5
+ Copyright (c) 1991-2013 iMatix Corporation <www.imatix.com>
6
+ Copyright other contributors as noted in the AUTHORS file.
7
+
8
+ This file is part of CZMQ, the high-level C binding for 0MQ:
9
+ http://czmq.zeromq.org.
10
+
11
+ This is free software; you can redistribute it and/or modify it under
12
+ the terms of the GNU Lesser General Public License as published by the
13
+ Free Software Foundation; either version 3 of the License, or (at your
14
+ option) any later version.
15
+
16
+ This software is distributed in the hope that it will be useful, but
17
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABIL-
18
+ ITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
19
+ Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
23
+ =========================================================================
24
+ */
25
+
26
+ /*
27
+ @header
28
+ The zbeacon class implements a peer-to-peer discovery service for local
29
+ networks. A beacon can broadcast and/or capture service announcements
30
+ using UDP messages on the local area network. This implementation uses
31
+ IPv4 UDP broadcasts. You can define the format of your outgoing beacons,
32
+ and set a filter that validates incoming beacons. Beacons are sent and
33
+ received asynchronously in the background. The zbeacon API provides a
34
+ incoming beacons on a ZeroMQ socket (the pipe) that you can configure,
35
+ poll on, and receive messages on. Incoming beacons are always delivered
36
+ as two frames: the ipaddress of the sender (a string), and the beacon
37
+ data itself (binary, as published).
38
+ @discuss
39
+ @end
40
+ */
41
+
42
+ #include "../include/czmq.h"
43
+ #if !defined (__WINDOWS__)
44
+ # include "platform.h"
45
+ #endif
46
+
47
+ #if defined (HAVE_LINUX_WIRELESS_H)
48
+ # include <linux/wireless.h>
49
+ #else
50
+ # if defined (HAVE_NET_IF_H)
51
+ # include <net/if.h>
52
+ # endif
53
+ # if defined (HAVE_NET_IF_MEDIA_H)
54
+ # include <net/if_media.h>
55
+ # endif
56
+ #endif
57
+
58
+ #if defined (__UTYPE_SUNSOLARIS) || defined (__UTYPE_SUNOS)
59
+ # include <ifaddrs.h>
60
+ # include <sys/sockio.h>
61
+ #endif
62
+
63
+ #if defined (__WINDOWS__)
64
+ # if (_WIN32_WINNT < 0x0501)
65
+ # undef _WIN32_WINNT
66
+ # define _WIN32_WINNT 0x0501
67
+ # endif
68
+ # include <ws2tcpip.h> // For getnameinfo ()
69
+ # include <iphlpapi.h> // For GetAdaptersAddresses ()
70
+ #endif
71
+
72
+ // Windows uses
73
+ #if !defined (__WINDOWS__)
74
+ typedef int SOCKET;
75
+ # define closesocket close
76
+ # define INVALID_SOCKET -1
77
+ # define SOCKET_ERROR -1
78
+ #endif
79
+
80
+ // Constants
81
+ #define BEACON_MAX 255 // Max size of beacon data
82
+ #define INTERVAL_DFLT 1000 // Default interval = 1 second
83
+
84
+ // Internet socket address structure
85
+ typedef struct sockaddr_in inaddr_t;
86
+
87
+ // Structure of our class
88
+ struct _zbeacon_t {
89
+ zctx_t *ctx; // Private 0MQ context
90
+ void *pipe; // Pipe through to backend agent
91
+ char *hostname; // Our own address as string
92
+ };
93
+
94
+
95
+ // Background task does the real I/O
96
+ static void
97
+ s_agent_task (void *args, zctx_t *ctx, void *pipe);
98
+
99
+
100
+ // --------------------------------------------------------------------------
101
+ // Create a new beacon
102
+
103
+ zbeacon_t *
104
+ zbeacon_new (int port_nbr)
105
+ {
106
+ zbeacon_t *self = (zbeacon_t *) zmalloc (sizeof (zbeacon_t));
107
+
108
+ // For now, we use a context per beacon instance
109
+ self->ctx = zctx_new ();
110
+
111
+ // Start beacon background agent
112
+ self->pipe = zthread_fork (self->ctx, s_agent_task, NULL);
113
+
114
+ // Configure agent with arguments
115
+ zstr_send (self->pipe, "%d", port_nbr);
116
+
117
+ // Agent replies with our host name
118
+ self->hostname = zstr_recv (self->pipe);
119
+
120
+ return self;
121
+ }
122
+
123
+
124
+ // --------------------------------------------------------------------------
125
+ // Destructor
126
+
127
+ void
128
+ zbeacon_destroy (zbeacon_t **self_p)
129
+ {
130
+ assert (self_p);
131
+ if (*self_p) {
132
+ zbeacon_t *self = *self_p;
133
+ zstr_send (self->pipe, "TERMINATE");
134
+ free (zstr_recv (self->pipe));
135
+ zctx_destroy (&self->ctx);
136
+ free (self->hostname);
137
+ free (self);
138
+ *self_p = NULL;
139
+ }
140
+ }
141
+
142
+
143
+ // --------------------------------------------------------------------------
144
+ // Set broadcast interval in milliseconds
145
+
146
+ void
147
+ zbeacon_set_interval (zbeacon_t *self, int interval)
148
+ {
149
+ assert (self);
150
+ zstr_sendm (self->pipe, "INTERVAL");
151
+ zstr_send (self->pipe, "%d", interval);
152
+ }
153
+
154
+
155
+ // --------------------------------------------------------------------------
156
+ // Filter out any beacon that looks exactly like ours
157
+
158
+ void
159
+ zbeacon_noecho (zbeacon_t *self)
160
+ {
161
+ assert (self);
162
+ zstr_send (self->pipe, "NOECHO");
163
+ }
164
+
165
+
166
+ // --------------------------------------------------------------------------
167
+ // Start broadcasting beacon to peers at the specified interval
168
+
169
+ void
170
+ zbeacon_publish (zbeacon_t *self, byte *transmit, size_t size)
171
+ {
172
+ assert (self);
173
+ assert (transmit);
174
+ assert (size > 0 && size <= BEACON_MAX);
175
+ zmsg_t *msg = zmsg_new ();
176
+ zmsg_addstr (msg, "PUBLISH");
177
+ zmsg_addmem (msg, transmit, size);
178
+ zmsg_send (&msg, self->pipe);
179
+ }
180
+
181
+
182
+ // --------------------------------------------------------------------------
183
+ // Stop broadcasting beacons
184
+
185
+ void
186
+ zbeacon_silence (zbeacon_t *self)
187
+ {
188
+ assert (self);
189
+ zstr_send (self->pipe, "SILENCE");
190
+ }
191
+
192
+
193
+ // --------------------------------------------------------------------------
194
+ // Start listening to other peers; zero-sized filter means get everything
195
+
196
+ void
197
+ zbeacon_subscribe (zbeacon_t *self, byte *filter, size_t size)
198
+ {
199
+ assert (self);
200
+ assert (size <= BEACON_MAX);
201
+ zmsg_t *msg = zmsg_new ();
202
+ zmsg_addstr (msg, "SUBSCRIBE");
203
+ zmsg_addmem (msg, filter, size);
204
+ zmsg_send (&msg, self->pipe);
205
+ }
206
+
207
+
208
+ // --------------------------------------------------------------------------
209
+ // Stop listening to other peers
210
+
211
+ void
212
+ zbeacon_unsubscribe (zbeacon_t *self)
213
+ {
214
+ zstr_send (self->pipe, "UNSUBSCRIBE");
215
+ }
216
+
217
+
218
+ // --------------------------------------------------------------------------
219
+ // Get beacon ZeroMQ socket, for polling or receiving messages
220
+
221
+ void *
222
+ zbeacon_socket (zbeacon_t *self)
223
+ {
224
+ assert (self);
225
+ return self->pipe;
226
+ }
227
+
228
+
229
+ // --------------------------------------------------------------------------
230
+ // Get beacon socket handle, for polling - DEPRECATED
231
+
232
+ void *
233
+ zbeacon_pipe (zbeacon_t *self)
234
+ {
235
+ assert (self);
236
+ return self->pipe;
237
+ }
238
+
239
+
240
+ // --------------------------------------------------------------------------
241
+ // Return our own IP address as printable string
242
+
243
+ char *
244
+ zbeacon_hostname (zbeacon_t *self)
245
+ {
246
+ assert (self);
247
+ return self->hostname;
248
+ }
249
+
250
+
251
+ // --------------------------------------------------------------------------
252
+ // Self test of this class
253
+
254
+ void
255
+ zbeacon_test (bool verbose)
256
+ {
257
+ printf (" * zbeacon: ");
258
+
259
+ // @selftest
260
+ // Basic test: create a service and announce it
261
+ zctx_t *ctx = zctx_new ();
262
+
263
+ // Create a service socket and bind to an ephemeral port
264
+ void *service = zsocket_new (ctx, ZMQ_PUB);
265
+ int port_nbr = zsocket_bind (service, "tcp://*:*");
266
+
267
+ // Create beacon to broadcast our service
268
+ byte announcement [2] = { (port_nbr >> 8) & 0xFF, port_nbr & 0xFF };
269
+ zbeacon_t *service_beacon = zbeacon_new (9999);
270
+ zbeacon_set_interval (service_beacon, 100);
271
+ zbeacon_publish (service_beacon, announcement, 2);
272
+
273
+ // Create beacon to lookup service
274
+ zbeacon_t *client_beacon = zbeacon_new (9999);
275
+ zbeacon_subscribe (client_beacon, NULL, 0);
276
+
277
+ // Wait for at most 1/2 second if there's no broadcast networking
278
+ zsocket_set_rcvtimeo (zbeacon_socket (client_beacon), 500);
279
+
280
+ char *ipaddress = zstr_recv (zbeacon_socket (client_beacon));
281
+ if (ipaddress) {
282
+ zframe_t *content = zframe_recv (zbeacon_socket (client_beacon));
283
+ int received_port = (zframe_data (content) [0] << 8)
284
+ + zframe_data (content) [1];
285
+ assert (received_port == port_nbr);
286
+ zframe_destroy (&content);
287
+ free (ipaddress);
288
+ }
289
+ zbeacon_destroy (&client_beacon);
290
+ zbeacon_destroy (&service_beacon);
291
+ zctx_destroy (&ctx);
292
+
293
+ zbeacon_t *node1 = zbeacon_new (5670);
294
+ zbeacon_t *node2 = zbeacon_new (5670);
295
+ zbeacon_t *node3 = zbeacon_new (5670);
296
+
297
+ assert (*zbeacon_hostname (node1));
298
+ assert (*zbeacon_hostname (node2));
299
+ assert (*zbeacon_hostname (node3));
300
+
301
+ zbeacon_set_interval (node1, 250);
302
+ zbeacon_set_interval (node2, 250);
303
+ zbeacon_set_interval (node3, 250);
304
+ zbeacon_noecho (node1);
305
+ zbeacon_publish (node1, (byte *) "NODE/1", 6);
306
+ zbeacon_publish (node2, (byte *) "NODE/2", 6);
307
+ zbeacon_publish (node3, (byte *) "GARBAGE", 7);
308
+ zbeacon_subscribe (node1, (byte *) "NODE", 4);
309
+
310
+ // Poll on API pipe and on UDP socket
311
+ zmq_pollitem_t pollitems [] = {
312
+ { zbeacon_socket (node1), 0, ZMQ_POLLIN, 0 },
313
+ { zbeacon_socket (node2), 0, ZMQ_POLLIN, 0 },
314
+ { zbeacon_socket (node3), 0, ZMQ_POLLIN, 0 }
315
+ };
316
+ uint64_t stop_at = zclock_time () + 1000;
317
+ while (zclock_time () < stop_at) {
318
+ long timeout = (long) (stop_at - zclock_time ());
319
+ if (timeout < 0)
320
+ timeout = 0;
321
+ if (zmq_poll (pollitems, 3, timeout * ZMQ_POLL_MSEC) == -1)
322
+ break; // Interrupted
323
+
324
+ // We cannot get messages on nodes 2 and 3
325
+ assert ((pollitems [1].revents & ZMQ_POLLIN) == 0);
326
+ assert ((pollitems [2].revents & ZMQ_POLLIN) == 0);
327
+
328
+ // If we get a message on node 1, it must be NODE/2
329
+ if (pollitems [0].revents & ZMQ_POLLIN) {
330
+ char *ipaddress = zstr_recv (zbeacon_socket (node1));
331
+ char *beacon = zstr_recv (zbeacon_socket (node1));
332
+ assert (streq (beacon, "NODE/2"));
333
+ free (ipaddress);
334
+ free (beacon);
335
+ }
336
+ }
337
+ // Stop listening
338
+ zbeacon_unsubscribe (node1);
339
+
340
+ // Stop all node broadcasts
341
+ zbeacon_silence (node1);
342
+ zbeacon_silence (node2);
343
+ zbeacon_silence (node3);
344
+
345
+ // Destroy the test nodes
346
+ zbeacon_destroy (&node1);
347
+ zbeacon_destroy (&node2);
348
+ zbeacon_destroy (&node3);
349
+ // @end
350
+ printf ("OK\n");
351
+ }
352
+
353
+
354
+ // --------------------------------------------------------------------------
355
+ // Backend agent implementation
356
+
357
+ // Agent instance
358
+
359
+ typedef struct {
360
+ void *pipe; // Socket to talk back to application
361
+ SOCKET udpsock; // UDP socket for send/recv
362
+ int port_nbr; // UDP port number we work on
363
+ int interval; // Beacon broadcast interval
364
+ bool enabled; // Are we broadcasting?
365
+ bool noecho; // Ignore own (unique) beacons?
366
+ bool terminated; // API shut us down
367
+ uint64_t ping_at; // Next broadcast time
368
+ zframe_t *transmit; // Beacon transmit data
369
+ zframe_t *filter; // Beacon filter data
370
+ inaddr_t address; // Our own address
371
+ inaddr_t broadcast; // Our broadcast address
372
+ } agent_t;
373
+
374
+ // Prototypes for local functions we use in the agent
375
+
376
+ static agent_t *
377
+ s_agent_new (void *pipe, int port_nbr);
378
+ static void
379
+ s_agent_destroy (agent_t **self_p);
380
+ static void
381
+ s_handle_io_error (char *reason);
382
+ static void
383
+ s_get_interface (agent_t *self);
384
+ static bool
385
+ s_wireless_nic (const char* name);
386
+ static void
387
+ s_api_command (agent_t *self);
388
+ static void
389
+ s_beacon_send (agent_t *self);
390
+ static void
391
+ s_beacon_recv (agent_t *self);
392
+
393
+
394
+ // This is the background task
395
+
396
+ static void
397
+ s_agent_task (void *args, zctx_t *ctx, void *pipe)
398
+ {
399
+ // Get port argument from caller
400
+ char *port_str = zstr_recv (pipe);
401
+ assert (port_str);
402
+
403
+ // Create agent instance
404
+ agent_t *self = s_agent_new (pipe, atoi (port_str));
405
+ free (port_str);
406
+
407
+ while (!zctx_interrupted) {
408
+ // Poll on API pipe and on UDP socket
409
+ zmq_pollitem_t pollitems [] = {
410
+ { self->pipe, 0, ZMQ_POLLIN, 0 },
411
+ { NULL, self->udpsock, ZMQ_POLLIN, 0 }
412
+ };
413
+ long timeout = -1;
414
+ if (self->transmit) {
415
+ timeout = (long) (self->ping_at - zclock_time ());
416
+ if (timeout < 0)
417
+ timeout = 0;
418
+ }
419
+ if (zmq_poll (pollitems, 2, timeout * ZMQ_POLL_MSEC) == -1)
420
+ break; // Interrupted
421
+
422
+ if (pollitems [0].revents & ZMQ_POLLIN)
423
+ s_api_command (self);
424
+ if (pollitems [1].revents & ZMQ_POLLIN)
425
+ s_beacon_recv (self);
426
+
427
+ if (self->transmit
428
+ && zclock_time () >= self->ping_at) {
429
+ s_beacon_send (self);
430
+ self->ping_at = zclock_time () + self->interval;
431
+ }
432
+ if (self->terminated)
433
+ break;
434
+ }
435
+ s_agent_destroy (&self);
436
+ }
437
+
438
+
439
+ // Create and initialize new agent instance
440
+
441
+ static agent_t *
442
+ s_agent_new (void *pipe, int port_nbr)
443
+ {
444
+ agent_t *self = (agent_t *) zmalloc (sizeof (agent_t));
445
+ assert (self);
446
+
447
+ self->pipe = pipe;
448
+ self->port_nbr = port_nbr;
449
+ self->interval = INTERVAL_DFLT;
450
+
451
+ // Create our UDP socket
452
+ self->udpsock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
453
+ if (self->udpsock == INVALID_SOCKET)
454
+ s_handle_io_error ("socket");
455
+
456
+ // Ask operating system to let us do broadcasts from socket
457
+ int on = 1;
458
+ if (setsockopt (self->udpsock, SOL_SOCKET, SO_BROADCAST,
459
+ (char *) &on, sizeof (on)) == SOCKET_ERROR)
460
+ s_handle_io_error ("setsockopt (SO_BROADCAST)");
461
+
462
+ // Allow multiple owners to bind to socket; incoming
463
+ // messages will replicate to each owner
464
+ if (setsockopt (self->udpsock, SOL_SOCKET, SO_REUSEADDR,
465
+ (char *) &on, sizeof (on)) == SOCKET_ERROR)
466
+ s_handle_io_error ("setsockopt (SO_REUSEADDR)");
467
+
468
+ #if defined (SO_REUSEPORT)
469
+ // On some platforms we have to ask to reuse the port
470
+ if (setsockopt (self->udpsock, SOL_SOCKET, SO_REUSEPORT,
471
+ (char *) &on, sizeof (on)) == SOCKET_ERROR)
472
+ s_handle_io_error ("setsockopt (SO_REUSEPORT)");
473
+ #endif
474
+ // PROBLEM: this design will not survive the network interface
475
+ // being killed and restarted while the program is running
476
+
477
+ // Bind to the port on all interfaces
478
+ inaddr_t sockaddr = { 0 };
479
+ sockaddr.sin_family = AF_INET;
480
+ sockaddr.sin_port = htons (self->port_nbr);
481
+ sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
482
+ if (bind (self->udpsock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) == SOCKET_ERROR)
483
+ s_handle_io_error ("bind");
484
+
485
+ // Get the network interface
486
+ s_get_interface (self);
487
+
488
+ // Send our hostname back to API
489
+ char hostname [INET_ADDRSTRLEN];
490
+ getnameinfo ((struct sockaddr *) &self->address, sizeof (self->address),
491
+ hostname, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
492
+ zstr_send (pipe, hostname);
493
+
494
+ return self;
495
+ }
496
+
497
+
498
+ // Handle error from I/O operation
499
+
500
+ static void
501
+ s_handle_io_error (char *reason)
502
+ {
503
+ #if defined (__WINDOWS__)
504
+ switch (WSAGetLastError ()) {
505
+ case WSAEINTR: errno = EINTR; break;
506
+ case WSAEBADF: errno = EBADF; break;
507
+ case WSAEWOULDBLOCK: errno = EAGAIN; break;
508
+ case WSAEINPROGRESS: errno = EAGAIN; break;
509
+ case WSAENETDOWN: errno = ENETDOWN; break;
510
+ case WSAECONNRESET: errno = ECONNRESET; break;
511
+ case WSAECONNABORTED: errno = EPIPE; break;
512
+ case WSAESHUTDOWN: errno = ECONNRESET; break;
513
+ case WSAEINVAL: errno = EPIPE; break;
514
+ default: errno = GetLastError ();
515
+ }
516
+ #endif
517
+ if (errno == EAGAIN
518
+ || errno == ENETDOWN
519
+ || errno == EHOSTUNREACH
520
+ || errno == ENETUNREACH
521
+ || errno == EINTR
522
+ || errno == EPIPE
523
+ || errno == ECONNRESET
524
+ #if !defined (__WINDOWS__)
525
+ || errno == EPROTO
526
+ || errno == ENOPROTOOPT
527
+ || errno == EHOSTDOWN
528
+ || errno == EOPNOTSUPP
529
+ || errno == EWOULDBLOCK
530
+ #endif
531
+ #if defined (ENONET)
532
+ || errno == ENONET
533
+ #endif
534
+ )
535
+ return; // Ignore error and try again
536
+ else {
537
+ zclock_log ("E: (UDP) error '%s' on %s", strerror (errno), reason);
538
+ assert (false);
539
+ }
540
+ }
541
+
542
+
543
+ // Get the actual network interface we're working on
544
+ // Currently implemented for POSIX and for Windows
545
+
546
+ static void
547
+ s_get_interface (agent_t *self)
548
+ {
549
+ #if defined (__UNIX__)
550
+ # if defined (HAVE_GETIFADDRS) && defined (HAVE_FREEIFADDRS)
551
+ struct ifaddrs *interfaces;
552
+ if (getifaddrs (&interfaces) == 0) {
553
+ struct ifaddrs *interface = interfaces;
554
+ while (interface) {
555
+ // Hopefully the last interface will be WiFi or Ethernet
556
+ if (interface->ifa_addr &&
557
+ interface->ifa_broadaddr && // on Solaris, loopback interfaces have a NULL in ifa_broadaddr
558
+ (interface->ifa_addr->sa_family == AF_INET)) {
559
+ self->address = *(inaddr_t *) interface->ifa_addr;
560
+ self->broadcast = *(inaddr_t *) interface->ifa_broadaddr;
561
+ self->broadcast.sin_port = htons (self->port_nbr);
562
+ if (streq (interface->ifa_name, zsys_interface ())
563
+ || s_wireless_nic (interface->ifa_name))
564
+ break;
565
+ }
566
+ interface = interface->ifa_next;
567
+ }
568
+ }
569
+ freeifaddrs (interfaces);
570
+ # else
571
+ struct ifreq ifr;
572
+ memset (&ifr, 0, sizeof (ifr));
573
+
574
+ int sock = 0;
575
+ if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
576
+ s_handle_io_error ("socket");
577
+
578
+ // Get interface address
579
+ ifr.ifr_addr.sa_family = AF_INET;
580
+ strncpy (ifr.ifr_name, zsys_interface (), sizeof (ifr.ifr_name));
581
+ int rc = ioctl (sock, SIOCGIFADDR, (caddr_t) &ifr, sizeof (struct ifreq));
582
+ if (rc == -1)
583
+ s_handle_io_error ("siocgifaddr");
584
+
585
+ // Get interface broadcast address
586
+ memcpy (&self->address, ((inaddr_t *) &ifr.ifr_addr),
587
+ sizeof (inaddr_t));
588
+ rc = ioctl (sock, SIOCGIFBRDADDR, (caddr_t) &ifr, sizeof (struct ifreq));
589
+ if (rc == -1)
590
+ s_handle_io_error ("siocgifbrdaddr");
591
+
592
+ memcpy (&self->broadcast, ((inaddr_t *) &ifr.ifr_broadaddr), sizeof (inaddr_t));
593
+ close (sock);
594
+ # endif
595
+
596
+ # elif defined (__WINDOWS__)
597
+ ULONG addr_size = 0;
598
+ DWORD rc = GetAdaptersAddresses (AF_INET,
599
+ GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &addr_size);
600
+ assert (rc == ERROR_BUFFER_OVERFLOW);
601
+
602
+ PIP_ADAPTER_ADDRESSES pip_addresses = (PIP_ADAPTER_ADDRESSES) malloc (addr_size);
603
+ rc = GetAdaptersAddresses (AF_INET,
604
+ GAA_FLAG_INCLUDE_PREFIX, NULL, pip_addresses, &addr_size);
605
+ assert (rc == NO_ERROR);
606
+
607
+ PIP_ADAPTER_ADDRESSES cur_address = pip_addresses;
608
+ while (cur_address) {
609
+ PIP_ADAPTER_UNICAST_ADDRESS pUnicast = cur_address->FirstUnicastAddress;
610
+ PIP_ADAPTER_PREFIX pPrefix = cur_address->FirstPrefix;
611
+
612
+ if (pUnicast && pPrefix) {
613
+ self->address = *(inaddr_t *)(pUnicast->Address.lpSockaddr);
614
+ self->broadcast = *(inaddr_t *)(pPrefix->Address.lpSockaddr);
615
+ self->broadcast.sin_addr.s_addr |= htonl ((1 << (32 - pPrefix->PrefixLength)) - 1);
616
+ }
617
+ cur_address = cur_address->Next;
618
+ }
619
+ free (pip_addresses);
620
+ # else
621
+ # error "Interface detection TBD on this operating system"
622
+ # endif
623
+
624
+ // Set broadcast address and port
625
+ self->broadcast.sin_addr.s_addr = INADDR_BROADCAST;
626
+ self->broadcast.sin_port = htons (self->port_nbr);
627
+ }
628
+
629
+ // Check if a given NIC name is wireless
630
+
631
+ static bool
632
+ s_wireless_nic (const char *name)
633
+ {
634
+ SOCKET udpsock = socket (AF_INET, SOCK_DGRAM, 0);
635
+ if (udpsock == INVALID_SOCKET)
636
+ s_handle_io_error ("socket");
637
+
638
+ bool is_nic = false;
639
+ #if defined (SIOCGIFMEDIA)
640
+ struct ifmediareq ifmr;
641
+ memset (&ifmr, 0, sizeof (struct ifmediareq));
642
+ strncpy(ifmr.ifm_name, name, sizeof (ifmr.ifm_name));
643
+ int res = ioctl (udpsock, SIOCGIFMEDIA, (caddr_t) &ifmr);
644
+ if (res != -1)
645
+ is_nic = (IFM_TYPE (ifmr.ifm_current) == IFM_IEEE80211);
646
+
647
+ #elif defined (SIOCGIWNAME)
648
+ struct iwreq wrq;
649
+ memset (&wrq, 0, sizeof (struct iwreq));
650
+ strncpy (wrq.ifr_name, name, sizeof (wrq.ifr_name));
651
+ int res = ioctl (udpsock, SIOCGIWNAME, (caddr_t) &wrq);
652
+ if (res != -1)
653
+ is_nic = true;
654
+ #endif
655
+ closesocket (udpsock);
656
+ return is_nic;
657
+ }
658
+
659
+ // Handle command from API
660
+
661
+ static void
662
+ s_api_command (agent_t *self)
663
+ {
664
+ char *command = zstr_recv (self->pipe);
665
+ if (streq (command, "INTERVAL")) {
666
+ char *interval = zstr_recv (self->pipe);
667
+ self->interval = atoi (interval);
668
+ free (interval);
669
+ }
670
+ else
671
+ if (streq (command, "NOECHO"))
672
+ self->noecho = true;
673
+ else
674
+ if (streq (command, "PUBLISH")) {
675
+ zframe_destroy (&self->transmit);
676
+ self->transmit = zframe_recv (self->pipe);
677
+ assert (self->transmit);
678
+ // Start broadcasting immediately
679
+ self->ping_at = zclock_time ();
680
+ }
681
+ else
682
+ if (streq (command, "SILENCE"))
683
+ zframe_destroy (&self->transmit);
684
+ else
685
+ if (streq (command, "SUBSCRIBE")) {
686
+ zframe_destroy (&self->filter);
687
+ self->filter = zframe_recv (self->pipe);
688
+ }
689
+ else
690
+ if (streq (command, "UNSUBSCRIBE"))
691
+ zframe_destroy (&self->filter);
692
+ else
693
+ if (streq (command, "TERMINATE")) {
694
+ self->terminated = true;
695
+ zstr_send (self->pipe, "OK");
696
+ }
697
+ else
698
+ printf ("E: unexpected API command '%s'\n", command);
699
+
700
+ free (command);
701
+ }
702
+
703
+ // Receive and filter the waiting beacon
704
+
705
+ static void
706
+ s_beacon_recv (agent_t *self)
707
+ {
708
+ assert (self);
709
+
710
+ socklen_t si_len = sizeof (inaddr_t);
711
+ inaddr_t sender;
712
+ byte buffer [BEACON_MAX];
713
+ ssize_t size = recvfrom (
714
+ self->udpsock,
715
+ (char *) buffer, BEACON_MAX,
716
+ 0, // Flags
717
+ (struct sockaddr *) &sender, &si_len);
718
+ if (size == SOCKET_ERROR)
719
+ s_handle_io_error ("recvfrom");
720
+
721
+ // Get sender address as printable string
722
+ char peername [INET_ADDRSTRLEN];
723
+ #if (defined (__WINDOWS__))
724
+ getnameinfo ((struct sockaddr *) &sender, si_len,
725
+ peername, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
726
+ #else
727
+ inet_ntop (AF_INET, &sender.sin_addr, peername, si_len);
728
+ #endif
729
+
730
+ // If filter is set, check that beacon matches it
731
+ bool is_valid = false;
732
+ if (self->filter) {
733
+ byte *filter_data = zframe_data (self->filter);
734
+ size_t filter_size = zframe_size (self->filter);
735
+ if (size >= filter_size && memcmp (buffer, filter_data, filter_size) == 0)
736
+ is_valid = true;
737
+ }
738
+ // If valid, check for echoed beacons (i.e. our own broadcast)
739
+ if (is_valid && self->noecho) {
740
+ byte *transmit_data = zframe_data (self->transmit);
741
+ size_t transmit_size = zframe_size (self->transmit);
742
+ if (size == transmit_size && memcmp (buffer, transmit_data, transmit_size) == 0)
743
+ is_valid = false;
744
+ }
745
+ // If still a valid beacon, send on to the API
746
+ if (is_valid) {
747
+ zmsg_t *msg = zmsg_new ();
748
+ zmsg_addstr (msg, peername);
749
+ zmsg_addmem (msg, buffer, size);
750
+ zmsg_send (&msg, self->pipe);
751
+ }
752
+ }
753
+
754
+ // Send beacon to any listening peers
755
+
756
+ static void
757
+ s_beacon_send (agent_t *self)
758
+ {
759
+ // Send UDP broadcast packet now
760
+ assert (self->transmit);
761
+ ssize_t size = sendto (
762
+ self->udpsock,
763
+ (char *) zframe_data (self->transmit), zframe_size (self->transmit),
764
+ 0, // Flags
765
+ (struct sockaddr *) &self->broadcast, sizeof (inaddr_t));
766
+ // Sending can fail if the OS is blocking multicast. In such cases we
767
+ // don't try to report the error. We might log this or send to an error
768
+ // console at some point.
769
+ if (size == SOCKET_ERROR)
770
+ ; // s_handle_io_error ("sendto");
771
+ }
772
+
773
+ // Destroy agent instance
774
+
775
+ static void
776
+ s_agent_destroy (agent_t **self_p)
777
+ {
778
+ assert (self_p);
779
+ if (*self_p) {
780
+ agent_t *self = *self_p;
781
+ closesocket (self->udpsock);
782
+ zframe_destroy (&self->transmit);
783
+ zframe_destroy (&self->filter);
784
+ free (self);
785
+ *self_p = NULL;
786
+ }
787
+ }