asyncengine 0.0.1.testing
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.
- data/README.markdown +0 -0
- data/asyncengine.gemspec +26 -0
- data/ext/asyncengine_ext/asyncengine_ruby.c +82 -0
- data/ext/asyncengine_ext/extconf.rb +47 -0
- data/ext/asyncengine_ext/libuv/AUTHORS +45 -0
- data/ext/asyncengine_ext/libuv/LICENSE +42 -0
- data/ext/asyncengine_ext/libuv/Makefile +119 -0
- data/ext/asyncengine_ext/libuv/README.md +88 -0
- data/ext/asyncengine_ext/libuv/build/gcc_version.py +20 -0
- data/ext/asyncengine_ext/libuv/common.gypi +176 -0
- data/ext/asyncengine_ext/libuv/config-mingw.mk +61 -0
- data/ext/asyncengine_ext/libuv/config-unix.mk +173 -0
- data/ext/asyncengine_ext/libuv/gyp_uv +60 -0
- data/ext/asyncengine_ext/libuv/include/ares.h +591 -0
- data/ext/asyncengine_ext/libuv/include/ares_version.h +24 -0
- data/ext/asyncengine_ext/libuv/include/uv-private/eio.h +403 -0
- data/ext/asyncengine_ext/libuv/include/uv-private/ev.h +838 -0
- data/ext/asyncengine_ext/libuv/include/uv-private/ngx-queue.h +106 -0
- data/ext/asyncengine_ext/libuv/include/uv-private/tree.h +768 -0
- data/ext/asyncengine_ext/libuv/include/uv-private/uv-unix.h +256 -0
- data/ext/asyncengine_ext/libuv/include/uv-private/uv-win.h +458 -0
- data/ext/asyncengine_ext/libuv/include/uv.h +1556 -0
- data/ext/asyncengine_ext/libuv/src/ares/AUTHORS +37 -0
- data/ext/asyncengine_ext/libuv/src/ares/CHANGES +1218 -0
- data/ext/asyncengine_ext/libuv/src/ares/CMakeLists.txt +22 -0
- data/ext/asyncengine_ext/libuv/src/ares/NEWS +21 -0
- data/ext/asyncengine_ext/libuv/src/ares/README +60 -0
- data/ext/asyncengine_ext/libuv/src/ares/README.cares +13 -0
- data/ext/asyncengine_ext/libuv/src/ares/README.msvc +142 -0
- data/ext/asyncengine_ext/libuv/src/ares/README.node +21 -0
- data/ext/asyncengine_ext/libuv/src/ares/RELEASE-NOTES +26 -0
- data/ext/asyncengine_ext/libuv/src/ares/TODO +23 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares__close_sockets.c +66 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares__get_hostent.c +263 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares__read_line.c +71 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares__timeval.c +111 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_cancel.c +63 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_data.c +190 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_data.h +65 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_destroy.c +105 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_dns.h +90 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_expand_name.c +200 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_expand_string.c +75 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_fds.c +63 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_free_hostent.c +42 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_free_string.c +25 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_getenv.c +30 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_getenv.h +26 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_gethostbyaddr.c +301 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_gethostbyname.c +523 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_getnameinfo.c +427 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_getopt.c +122 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_getopt.h +53 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_getsock.c +72 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_init.c +1809 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_iphlpapi.h +221 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_ipv6.h +78 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_library_init.c +142 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_library_init.h +42 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_llist.c +86 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_llist.h +42 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_mkquery.c +195 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_nowarn.c +181 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_nowarn.h +55 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_options.c +248 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_parse_a_reply.c +263 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_parse_aaaa_reply.c +259 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_parse_mx_reply.c +170 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_parse_ns_reply.c +182 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_parse_ptr_reply.c +217 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_parse_srv_reply.c +179 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_parse_txt_reply.c +201 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_platform.c +11035 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_platform.h +43 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_private.h +355 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_process.c +1295 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_query.c +183 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_rules.h +144 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_search.c +321 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_send.c +134 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_setup.h +199 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_strcasecmp.c +66 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_strcasecmp.h +30 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_strdup.c +42 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_strdup.h +26 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_strerror.c +56 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_timeout.c +80 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_version.c +11 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_writev.c +79 -0
- data/ext/asyncengine_ext/libuv/src/ares/ares_writev.h +36 -0
- data/ext/asyncengine_ext/libuv/src/ares/bitncmp.c +59 -0
- data/ext/asyncengine_ext/libuv/src/ares/bitncmp.h +26 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_cygwin/ares_config.h +512 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_darwin/ares_config.h +512 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_freebsd/ares_config.h +512 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_linux/ares_config.h +512 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_netbsd/ares_config.h +512 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_openbsd/ares_config.h +512 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_sunos/ares_config.h +512 -0
- data/ext/asyncengine_ext/libuv/src/ares/config_win32/ares_config.h +369 -0
- data/ext/asyncengine_ext/libuv/src/ares/get_ver.awk +35 -0
- data/ext/asyncengine_ext/libuv/src/ares/inet_net_pton.c +451 -0
- data/ext/asyncengine_ext/libuv/src/ares/inet_net_pton.h +31 -0
- data/ext/asyncengine_ext/libuv/src/ares/inet_ntop.c +208 -0
- data/ext/asyncengine_ext/libuv/src/ares/inet_ntop.h +26 -0
- data/ext/asyncengine_ext/libuv/src/ares/nameser.h +203 -0
- data/ext/asyncengine_ext/libuv/src/ares/setup_once.h +504 -0
- data/ext/asyncengine_ext/libuv/src/ares/windows_port.c +22 -0
- data/ext/asyncengine_ext/libuv/src/unix/async.c +58 -0
- data/ext/asyncengine_ext/libuv/src/unix/cares.c +194 -0
- data/ext/asyncengine_ext/libuv/src/unix/check.c +80 -0
- data/ext/asyncengine_ext/libuv/src/unix/core.c +588 -0
- data/ext/asyncengine_ext/libuv/src/unix/cygwin.c +84 -0
- data/ext/asyncengine_ext/libuv/src/unix/darwin.c +341 -0
- data/ext/asyncengine_ext/libuv/src/unix/dl.c +91 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/Changes +63 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/LICENSE +36 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/Makefile.am +15 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/aclocal.m4 +8957 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/autogen.sh +3 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config.h.in +86 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config_cygwin.h +80 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config_darwin.h +141 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config_freebsd.h +81 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config_linux.h +94 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config_netbsd.h +81 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config_openbsd.h +137 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/config_sunos.h +84 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/configure.ac +22 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/demo.c +194 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/ecb.h +370 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/eio.3 +3428 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/eio.c +2593 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/eio.pod +969 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/libeio.m4 +195 -0
- data/ext/asyncengine_ext/libuv/src/unix/eio/xthread.h +164 -0
- data/ext/asyncengine_ext/libuv/src/unix/error.c +98 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/Changes +388 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/LICENSE +36 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/Makefile.am +18 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/Makefile.in +771 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/README +58 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/aclocal.m4 +8957 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/autogen.sh +6 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config.guess +1526 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config.h.in +125 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config.sub +1658 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config_cygwin.h +123 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config_darwin.h +122 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config_freebsd.h +120 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config_linux.h +141 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config_netbsd.h +120 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config_openbsd.h +126 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/config_sunos.h +122 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/configure +13037 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/configure.ac +18 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/depcomp +630 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev++.h +816 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev.3 +5311 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev.c +3921 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev.pod +5243 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_epoll.c +266 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_kqueue.c +235 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_poll.c +148 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_port.c +179 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_select.c +310 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_vars.h +203 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_win32.c +153 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ev_wrap.h +196 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/event.c +402 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/event.h +170 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/install-sh +294 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/libev.m4 +39 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/ltmain.sh +8413 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/missing +336 -0
- data/ext/asyncengine_ext/libuv/src/unix/ev/mkinstalldirs +111 -0
- data/ext/asyncengine_ext/libuv/src/unix/freebsd.c +312 -0
- data/ext/asyncengine_ext/libuv/src/unix/fs.c +707 -0
- data/ext/asyncengine_ext/libuv/src/unix/idle.c +79 -0
- data/ext/asyncengine_ext/libuv/src/unix/internal.h +161 -0
- data/ext/asyncengine_ext/libuv/src/unix/kqueue.c +127 -0
- data/ext/asyncengine_ext/libuv/src/unix/linux/core.c +474 -0
- data/ext/asyncengine_ext/libuv/src/unix/linux/inotify.c +211 -0
- data/ext/asyncengine_ext/libuv/src/unix/linux/syscalls.c +230 -0
- data/ext/asyncengine_ext/libuv/src/unix/linux/syscalls.h +87 -0
- data/ext/asyncengine_ext/libuv/src/unix/loop.c +58 -0
- data/ext/asyncengine_ext/libuv/src/unix/netbsd.c +108 -0
- data/ext/asyncengine_ext/libuv/src/unix/openbsd.c +295 -0
- data/ext/asyncengine_ext/libuv/src/unix/pipe.c +266 -0
- data/ext/asyncengine_ext/libuv/src/unix/prepare.c +79 -0
- data/ext/asyncengine_ext/libuv/src/unix/process.c +369 -0
- data/ext/asyncengine_ext/libuv/src/unix/stream.c +1033 -0
- data/ext/asyncengine_ext/libuv/src/unix/sunos.c +466 -0
- data/ext/asyncengine_ext/libuv/src/unix/tcp.c +327 -0
- data/ext/asyncengine_ext/libuv/src/unix/thread.c +154 -0
- data/ext/asyncengine_ext/libuv/src/unix/timer.c +127 -0
- data/ext/asyncengine_ext/libuv/src/unix/tty.c +146 -0
- data/ext/asyncengine_ext/libuv/src/unix/udp.c +670 -0
- data/ext/asyncengine_ext/libuv/src/unix/uv-eio.c +124 -0
- data/ext/asyncengine_ext/libuv/src/unix/uv-eio.h +13 -0
- data/ext/asyncengine_ext/libuv/src/uv-common.c +354 -0
- data/ext/asyncengine_ext/libuv/src/uv-common.h +87 -0
- data/ext/asyncengine_ext/libuv/src/win/async.c +127 -0
- data/ext/asyncengine_ext/libuv/src/win/cares.c +290 -0
- data/ext/asyncengine_ext/libuv/src/win/core.c +270 -0
- data/ext/asyncengine_ext/libuv/src/win/dl.c +82 -0
- data/ext/asyncengine_ext/libuv/src/win/error.c +132 -0
- data/ext/asyncengine_ext/libuv/src/win/fs-event.c +514 -0
- data/ext/asyncengine_ext/libuv/src/win/fs.c +1576 -0
- data/ext/asyncengine_ext/libuv/src/win/getaddrinfo.c +372 -0
- data/ext/asyncengine_ext/libuv/src/win/handle.c +225 -0
- data/ext/asyncengine_ext/libuv/src/win/internal.h +352 -0
- data/ext/asyncengine_ext/libuv/src/win/loop-watcher.c +131 -0
- data/ext/asyncengine_ext/libuv/src/win/pipe.c +1661 -0
- data/ext/asyncengine_ext/libuv/src/win/process.c +1140 -0
- data/ext/asyncengine_ext/libuv/src/win/req.c +174 -0
- data/ext/asyncengine_ext/libuv/src/win/stream.c +201 -0
- data/ext/asyncengine_ext/libuv/src/win/tcp.c +1282 -0
- data/ext/asyncengine_ext/libuv/src/win/thread.c +332 -0
- data/ext/asyncengine_ext/libuv/src/win/threadpool.c +73 -0
- data/ext/asyncengine_ext/libuv/src/win/timer.c +276 -0
- data/ext/asyncengine_ext/libuv/src/win/tty.c +1795 -0
- data/ext/asyncengine_ext/libuv/src/win/udp.c +709 -0
- data/ext/asyncengine_ext/libuv/src/win/util.c +719 -0
- data/ext/asyncengine_ext/libuv/src/win/winapi.c +117 -0
- data/ext/asyncengine_ext/libuv/src/win/winapi.h +4419 -0
- data/ext/asyncengine_ext/libuv/src/win/winsock.c +470 -0
- data/ext/asyncengine_ext/libuv/src/win/winsock.h +138 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-ares.c +118 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-getaddrinfo.c +94 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-list.h +105 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-ping-pongs.c +213 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-pound.c +324 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-pump.c +462 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-sizes.c +40 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-spawn.c +156 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-tcp-write-batch.c +140 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-thread.c +64 -0
- data/ext/asyncengine_ext/libuv/test/benchmark-udp-packet-storm.c +247 -0
- data/ext/asyncengine_ext/libuv/test/blackhole-server.c +118 -0
- data/ext/asyncengine_ext/libuv/test/dns-server.c +321 -0
- data/ext/asyncengine_ext/libuv/test/echo-server.c +370 -0
- data/ext/asyncengine_ext/libuv/test/fixtures/empty_file +0 -0
- data/ext/asyncengine_ext/libuv/test/fixtures/load_error.node +1 -0
- data/ext/asyncengine_ext/libuv/test/run-benchmarks.c +64 -0
- data/ext/asyncengine_ext/libuv/test/run-tests.c +108 -0
- data/ext/asyncengine_ext/libuv/test/runner-unix.c +315 -0
- data/ext/asyncengine_ext/libuv/test/runner-unix.h +36 -0
- data/ext/asyncengine_ext/libuv/test/runner-win.c +343 -0
- data/ext/asyncengine_ext/libuv/test/runner-win.h +42 -0
- data/ext/asyncengine_ext/libuv/test/runner.c +317 -0
- data/ext/asyncengine_ext/libuv/test/runner.h +159 -0
- data/ext/asyncengine_ext/libuv/test/task.h +117 -0
- data/ext/asyncengine_ext/libuv/test/test-async.c +216 -0
- data/ext/asyncengine_ext/libuv/test/test-callback-stack.c +203 -0
- data/ext/asyncengine_ext/libuv/test/test-connection-fail.c +148 -0
- data/ext/asyncengine_ext/libuv/test/test-counters-init.c +216 -0
- data/ext/asyncengine_ext/libuv/test/test-cwd-and-chdir.c +64 -0
- data/ext/asyncengine_ext/libuv/test/test-delayed-accept.c +197 -0
- data/ext/asyncengine_ext/libuv/test/test-dlerror.c +49 -0
- data/ext/asyncengine_ext/libuv/test/test-eio-overflow.c +90 -0
- data/ext/asyncengine_ext/libuv/test/test-error.c +59 -0
- data/ext/asyncengine_ext/libuv/test/test-fail-always.c +29 -0
- data/ext/asyncengine_ext/libuv/test/test-fs-event.c +442 -0
- data/ext/asyncengine_ext/libuv/test/test-fs.c +1731 -0
- data/ext/asyncengine_ext/libuv/test/test-get-currentexe.c +63 -0
- data/ext/asyncengine_ext/libuv/test/test-get-loadavg.c +36 -0
- data/ext/asyncengine_ext/libuv/test/test-get-memory.c +38 -0
- data/ext/asyncengine_ext/libuv/test/test-getaddrinfo.c +122 -0
- data/ext/asyncengine_ext/libuv/test/test-gethostbyname.c +189 -0
- data/ext/asyncengine_ext/libuv/test/test-getsockname.c +342 -0
- data/ext/asyncengine_ext/libuv/test/test-hrtime.c +51 -0
- data/ext/asyncengine_ext/libuv/test/test-idle.c +81 -0
- data/ext/asyncengine_ext/libuv/test/test-ipc-send-recv.c +209 -0
- data/ext/asyncengine_ext/libuv/test/test-ipc.c +614 -0
- data/ext/asyncengine_ext/libuv/test/test-list.h +371 -0
- data/ext/asyncengine_ext/libuv/test/test-loop-handles.c +359 -0
- data/ext/asyncengine_ext/libuv/test/test-multiple-listen.c +102 -0
- data/ext/asyncengine_ext/libuv/test/test-mutexes.c +63 -0
- data/ext/asyncengine_ext/libuv/test/test-pass-always.c +28 -0
- data/ext/asyncengine_ext/libuv/test/test-ping-pong.c +253 -0
- data/ext/asyncengine_ext/libuv/test/test-pipe-bind-error.c +140 -0
- data/ext/asyncengine_ext/libuv/test/test-pipe-connect-error.c +96 -0
- data/ext/asyncengine_ext/libuv/test/test-platform-output.c +87 -0
- data/ext/asyncengine_ext/libuv/test/test-process-title.c +42 -0
- data/ext/asyncengine_ext/libuv/test/test-ref.c +322 -0
- data/ext/asyncengine_ext/libuv/test/test-run-once.c +44 -0
- data/ext/asyncengine_ext/libuv/test/test-shutdown-close.c +103 -0
- data/ext/asyncengine_ext/libuv/test/test-shutdown-eof.c +183 -0
- data/ext/asyncengine_ext/libuv/test/test-spawn.c +499 -0
- data/ext/asyncengine_ext/libuv/test/test-stdio-over-pipes.c +256 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-bind-error.c +191 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-bind6-error.c +154 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-close.c +129 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-connect-error.c +70 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-connect6-error.c +68 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-flags.c +51 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-write-error.c +168 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-write-to-half-open-connection.c +135 -0
- data/ext/asyncengine_ext/libuv/test/test-tcp-writealot.c +195 -0
- data/ext/asyncengine_ext/libuv/test/test-thread.c +183 -0
- data/ext/asyncengine_ext/libuv/test/test-threadpool.c +57 -0
- data/ext/asyncengine_ext/libuv/test/test-timer-again.c +141 -0
- data/ext/asyncengine_ext/libuv/test/test-timer.c +130 -0
- data/ext/asyncengine_ext/libuv/test/test-tty.c +110 -0
- data/ext/asyncengine_ext/libuv/test/test-udp-dgram-too-big.c +86 -0
- data/ext/asyncengine_ext/libuv/test/test-udp-ipv6.c +156 -0
- data/ext/asyncengine_ext/libuv/test/test-udp-multicast-join.c +139 -0
- data/ext/asyncengine_ext/libuv/test/test-udp-multicast-ttl.c +86 -0
- data/ext/asyncengine_ext/libuv/test/test-udp-options.c +86 -0
- data/ext/asyncengine_ext/libuv/test/test-udp-send-and-recv.c +208 -0
- data/ext/asyncengine_ext/libuv/test/test-util.c +97 -0
- data/ext/asyncengine_ext/libuv/uv.gyp +435 -0
- data/ext/asyncengine_ext/libuv/vcbuild.bat +105 -0
- data/lib/asyncengine/version.rb +3 -0
- data/lib/asyncengine.rb +41 -0
- metadata +384 -0
@@ -0,0 +1,709 @@
|
|
1
|
+
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
2
|
+
*
|
3
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
* of this software and associated documentation files (the "Software"), to
|
5
|
+
* deal in the Software without restriction, including without limitation the
|
6
|
+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
* sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
* furnished to do so, subject to the following conditions:
|
9
|
+
*
|
10
|
+
* The above copyright notice and this permission notice shall be included in
|
11
|
+
* all copies or substantial portions of the Software.
|
12
|
+
*
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
18
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
19
|
+
* IN THE SOFTWARE.
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include <assert.h>
|
23
|
+
|
24
|
+
#include "uv.h"
|
25
|
+
#include "../uv-common.h"
|
26
|
+
#include "internal.h"
|
27
|
+
|
28
|
+
|
29
|
+
/*
|
30
|
+
* Threshold of active udp streams for which to preallocate udp read buffers.
|
31
|
+
*/
|
32
|
+
const unsigned int uv_active_udp_streams_threshold = 0;
|
33
|
+
|
34
|
+
/* A zero-size buffer for use by uv_udp_read */
|
35
|
+
static char uv_zero_[] = "";
|
36
|
+
|
37
|
+
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
|
38
|
+
int* namelen) {
|
39
|
+
uv_loop_t* loop = handle->loop;
|
40
|
+
int result;
|
41
|
+
|
42
|
+
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
43
|
+
uv__set_sys_error(loop, WSAEINVAL);
|
44
|
+
return -1;
|
45
|
+
}
|
46
|
+
|
47
|
+
result = getsockname(handle->socket, name, namelen);
|
48
|
+
if (result != 0) {
|
49
|
+
uv__set_sys_error(loop, WSAGetLastError());
|
50
|
+
return -1;
|
51
|
+
}
|
52
|
+
|
53
|
+
return 0;
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
|
58
|
+
SOCKET socket) {
|
59
|
+
DWORD yes = 1;
|
60
|
+
WSAPROTOCOL_INFOW info;
|
61
|
+
int opt_len;
|
62
|
+
|
63
|
+
assert(handle->socket == INVALID_SOCKET);
|
64
|
+
|
65
|
+
/* Set the socket to nonblocking mode */
|
66
|
+
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
|
67
|
+
uv__set_sys_error(loop, WSAGetLastError());
|
68
|
+
return -1;
|
69
|
+
}
|
70
|
+
|
71
|
+
/* Make the socket non-inheritable */
|
72
|
+
if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
|
73
|
+
uv__set_sys_error(loop, GetLastError());
|
74
|
+
return -1;
|
75
|
+
}
|
76
|
+
|
77
|
+
/* Associate it with the I/O completion port. */
|
78
|
+
/* Use uv_handle_t pointer as completion key. */
|
79
|
+
if (CreateIoCompletionPort((HANDLE)socket,
|
80
|
+
loop->iocp,
|
81
|
+
(ULONG_PTR)socket,
|
82
|
+
0) == NULL) {
|
83
|
+
uv__set_sys_error(loop, GetLastError());
|
84
|
+
return -1;
|
85
|
+
}
|
86
|
+
|
87
|
+
if (pSetFileCompletionNotificationModes) {
|
88
|
+
/* All know windowses that support SetFileCompletionNotificationModes */
|
89
|
+
/* have a bug that makes it impossible to use this function in */
|
90
|
+
/* conjunction with datagram sockets. We can work around that but only */
|
91
|
+
/* if the user is using the default UDP driver (AFD) and has no other */
|
92
|
+
/* LSPs stacked on top. Here we check whether that is the case. */
|
93
|
+
opt_len = (int) sizeof info;
|
94
|
+
if (!getsockopt(socket,
|
95
|
+
SOL_SOCKET,
|
96
|
+
SO_PROTOCOL_INFOW,
|
97
|
+
(char*) &info,
|
98
|
+
&opt_len) == SOCKET_ERROR) {
|
99
|
+
uv__set_sys_error(loop, GetLastError());
|
100
|
+
return -1;
|
101
|
+
}
|
102
|
+
|
103
|
+
if (info.ProtocolChain.ChainLen == 1) {
|
104
|
+
if (pSetFileCompletionNotificationModes((HANDLE)socket,
|
105
|
+
FILE_SKIP_SET_EVENT_ON_HANDLE |
|
106
|
+
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
|
107
|
+
handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
|
108
|
+
handle->func_wsarecv = uv_wsarecv_workaround;
|
109
|
+
handle->func_wsarecvfrom = uv_wsarecvfrom_workaround;
|
110
|
+
} else if (GetLastError() != ERROR_INVALID_FUNCTION) {
|
111
|
+
uv__set_sys_error(loop, GetLastError());
|
112
|
+
return -1;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
handle->socket = socket;
|
118
|
+
|
119
|
+
return 0;
|
120
|
+
}
|
121
|
+
|
122
|
+
|
123
|
+
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
124
|
+
handle->type = UV_UDP;
|
125
|
+
handle->socket = INVALID_SOCKET;
|
126
|
+
handle->reqs_pending = 0;
|
127
|
+
handle->loop = loop;
|
128
|
+
handle->flags = 0;
|
129
|
+
handle->func_wsarecv = WSARecv;
|
130
|
+
handle->func_wsarecvfrom = WSARecvFrom;
|
131
|
+
|
132
|
+
uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
|
133
|
+
handle->recv_req.type = UV_UDP_RECV;
|
134
|
+
handle->recv_req.data = handle;
|
135
|
+
|
136
|
+
uv_ref(loop);
|
137
|
+
|
138
|
+
loop->counters.handle_init++;
|
139
|
+
loop->counters.udp_init++;
|
140
|
+
|
141
|
+
return 0;
|
142
|
+
}
|
143
|
+
|
144
|
+
|
145
|
+
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
|
146
|
+
if (handle->flags & UV_HANDLE_CLOSING &&
|
147
|
+
handle->reqs_pending == 0) {
|
148
|
+
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
149
|
+
handle->flags |= UV_HANDLE_CLOSED;
|
150
|
+
|
151
|
+
if (handle->close_cb) {
|
152
|
+
handle->close_cb((uv_handle_t*)handle);
|
153
|
+
}
|
154
|
+
|
155
|
+
uv_unref(loop);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
|
160
|
+
static int uv__bind(uv_udp_t* handle,
|
161
|
+
int domain,
|
162
|
+
struct sockaddr* addr,
|
163
|
+
int addrsize,
|
164
|
+
unsigned int flags) {
|
165
|
+
int r;
|
166
|
+
DWORD no = 0, yes = 1;
|
167
|
+
|
168
|
+
if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
|
169
|
+
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
|
170
|
+
uv__set_artificial_error(handle->loop, UV_EINVAL);
|
171
|
+
return -1;
|
172
|
+
}
|
173
|
+
|
174
|
+
if (handle->socket == INVALID_SOCKET) {
|
175
|
+
SOCKET sock = socket(domain, SOCK_DGRAM, 0);
|
176
|
+
if (sock == INVALID_SOCKET) {
|
177
|
+
uv__set_sys_error(handle->loop, WSAGetLastError());
|
178
|
+
return -1;
|
179
|
+
}
|
180
|
+
|
181
|
+
if (uv_udp_set_socket(handle->loop, handle, sock) == -1) {
|
182
|
+
closesocket(sock);
|
183
|
+
return -1;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
if (domain == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
|
188
|
+
/* On windows IPV6ONLY is on by default. */
|
189
|
+
/* If the user doesn't specify it libuv turns it off. */
|
190
|
+
|
191
|
+
/* TODO: how to handle errors? This may fail if there is no ipv4 stack */
|
192
|
+
/* available, or when run on XP/2003 which have no support for dualstack */
|
193
|
+
/* sockets. For now we're silently ignoring the error. */
|
194
|
+
setsockopt(handle->socket,
|
195
|
+
IPPROTO_IPV6,
|
196
|
+
IPV6_V6ONLY,
|
197
|
+
(char*) &no,
|
198
|
+
sizeof no);
|
199
|
+
}
|
200
|
+
|
201
|
+
r = setsockopt(handle->socket,
|
202
|
+
SOL_SOCKET,
|
203
|
+
SO_REUSEADDR,
|
204
|
+
(char*) &yes,
|
205
|
+
sizeof yes);
|
206
|
+
if (r == SOCKET_ERROR) {
|
207
|
+
uv__set_sys_error(handle->loop, WSAGetLastError());
|
208
|
+
return -1;
|
209
|
+
}
|
210
|
+
|
211
|
+
r = bind(handle->socket, addr, addrsize);
|
212
|
+
if (r == SOCKET_ERROR) {
|
213
|
+
uv__set_sys_error(handle->loop, WSAGetLastError());
|
214
|
+
return -1;
|
215
|
+
}
|
216
|
+
|
217
|
+
handle->flags |= UV_HANDLE_BOUND;
|
218
|
+
|
219
|
+
return 0;
|
220
|
+
}
|
221
|
+
|
222
|
+
|
223
|
+
int uv__udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
|
224
|
+
unsigned int flags) {
|
225
|
+
return uv__bind(handle,
|
226
|
+
AF_INET,
|
227
|
+
(struct sockaddr*) &addr,
|
228
|
+
sizeof(struct sockaddr_in),
|
229
|
+
flags);
|
230
|
+
}
|
231
|
+
|
232
|
+
|
233
|
+
int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
|
234
|
+
unsigned int flags) {
|
235
|
+
if (uv_allow_ipv6) {
|
236
|
+
handle->flags |= UV_HANDLE_IPV6;
|
237
|
+
return uv__bind(handle,
|
238
|
+
AF_INET6,
|
239
|
+
(struct sockaddr*) &addr,
|
240
|
+
sizeof(struct sockaddr_in6),
|
241
|
+
flags);
|
242
|
+
} else {
|
243
|
+
uv__set_sys_error(handle->loop, WSAEAFNOSUPPORT);
|
244
|
+
return -1;
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
|
249
|
+
static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
|
250
|
+
uv_req_t* req;
|
251
|
+
uv_buf_t buf;
|
252
|
+
DWORD bytes, flags;
|
253
|
+
int result;
|
254
|
+
|
255
|
+
assert(handle->flags & UV_HANDLE_READING);
|
256
|
+
assert(!(handle->flags & UV_HANDLE_READ_PENDING));
|
257
|
+
|
258
|
+
req = &handle->recv_req;
|
259
|
+
memset(&req->overlapped, 0, sizeof(req->overlapped));
|
260
|
+
|
261
|
+
/*
|
262
|
+
* Preallocate a read buffer if the number of active streams is below
|
263
|
+
* the threshold.
|
264
|
+
*/
|
265
|
+
if (loop->active_udp_streams < uv_active_udp_streams_threshold) {
|
266
|
+
handle->flags &= ~UV_HANDLE_ZERO_READ;
|
267
|
+
|
268
|
+
handle->recv_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536);
|
269
|
+
assert(handle->recv_buffer.len > 0);
|
270
|
+
|
271
|
+
buf = handle->recv_buffer;
|
272
|
+
memset(&handle->recv_from, 0, sizeof handle->recv_from);
|
273
|
+
handle->recv_from_len = sizeof handle->recv_from;
|
274
|
+
flags = 0;
|
275
|
+
|
276
|
+
result = handle->func_wsarecvfrom(handle->socket,
|
277
|
+
(WSABUF*) &buf,
|
278
|
+
1,
|
279
|
+
&bytes,
|
280
|
+
&flags,
|
281
|
+
(struct sockaddr*) &handle->recv_from,
|
282
|
+
&handle->recv_from_len,
|
283
|
+
&req->overlapped,
|
284
|
+
NULL);
|
285
|
+
|
286
|
+
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
|
287
|
+
/* Process the req without IOCP. */
|
288
|
+
handle->flags |= UV_HANDLE_READ_PENDING;
|
289
|
+
req->overlapped.InternalHigh = bytes;
|
290
|
+
handle->reqs_pending++;
|
291
|
+
uv_insert_pending_req(loop, req);
|
292
|
+
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
293
|
+
/* The req will be processed with IOCP. */
|
294
|
+
handle->flags |= UV_HANDLE_READ_PENDING;
|
295
|
+
handle->reqs_pending++;
|
296
|
+
} else {
|
297
|
+
/* Make this req pending reporting an error. */
|
298
|
+
SET_REQ_ERROR(req, WSAGetLastError());
|
299
|
+
uv_insert_pending_req(loop, req);
|
300
|
+
handle->reqs_pending++;
|
301
|
+
}
|
302
|
+
|
303
|
+
} else {
|
304
|
+
handle->flags |= UV_HANDLE_ZERO_READ;
|
305
|
+
|
306
|
+
buf.base = (char*) uv_zero_;
|
307
|
+
buf.len = 0;
|
308
|
+
flags = MSG_PEEK;
|
309
|
+
|
310
|
+
result = handle->func_wsarecv(handle->socket,
|
311
|
+
(WSABUF*) &buf,
|
312
|
+
1,
|
313
|
+
&bytes,
|
314
|
+
&flags,
|
315
|
+
&req->overlapped,
|
316
|
+
NULL);
|
317
|
+
|
318
|
+
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
|
319
|
+
/* Process the req without IOCP. */
|
320
|
+
handle->flags |= UV_HANDLE_READ_PENDING;
|
321
|
+
req->overlapped.InternalHigh = bytes;
|
322
|
+
handle->reqs_pending++;
|
323
|
+
uv_insert_pending_req(loop, req);
|
324
|
+
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
325
|
+
/* The req will be processed with IOCP. */
|
326
|
+
handle->flags |= UV_HANDLE_READ_PENDING;
|
327
|
+
handle->reqs_pending++;
|
328
|
+
} else {
|
329
|
+
/* Make this req pending reporting an error. */
|
330
|
+
SET_REQ_ERROR(req, WSAGetLastError());
|
331
|
+
uv_insert_pending_req(loop, req);
|
332
|
+
handle->reqs_pending++;
|
333
|
+
}
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
|
338
|
+
int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
|
339
|
+
uv_udp_recv_cb recv_cb) {
|
340
|
+
uv_loop_t* loop = handle->loop;
|
341
|
+
|
342
|
+
if (handle->flags & UV_HANDLE_READING) {
|
343
|
+
uv__set_sys_error(loop, WSAEALREADY);
|
344
|
+
return -1;
|
345
|
+
}
|
346
|
+
|
347
|
+
if (!(handle->flags & UV_HANDLE_BOUND) &&
|
348
|
+
uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) {
|
349
|
+
return -1;
|
350
|
+
}
|
351
|
+
|
352
|
+
handle->flags |= UV_HANDLE_READING;
|
353
|
+
loop->active_udp_streams++;
|
354
|
+
|
355
|
+
handle->recv_cb = recv_cb;
|
356
|
+
handle->alloc_cb = alloc_cb;
|
357
|
+
|
358
|
+
/* If reading was stopped and then started again, there could still be a */
|
359
|
+
/* recv request pending. */
|
360
|
+
if (!(handle->flags & UV_HANDLE_READ_PENDING))
|
361
|
+
uv_udp_queue_recv(loop, handle);
|
362
|
+
|
363
|
+
return 0;
|
364
|
+
}
|
365
|
+
|
366
|
+
|
367
|
+
int uv_udp_recv_stop(uv_udp_t* handle) {
|
368
|
+
if (handle->flags & UV_HANDLE_READING) {
|
369
|
+
handle->flags &= ~UV_HANDLE_READING;
|
370
|
+
handle->loop->active_udp_streams--;
|
371
|
+
}
|
372
|
+
|
373
|
+
return 0;
|
374
|
+
}
|
375
|
+
|
376
|
+
|
377
|
+
static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
|
378
|
+
int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) {
|
379
|
+
uv_loop_t* loop = handle->loop;
|
380
|
+
DWORD result, bytes;
|
381
|
+
|
382
|
+
uv_req_init(loop, (uv_req_t*) req);
|
383
|
+
req->type = UV_UDP_SEND;
|
384
|
+
req->handle = handle;
|
385
|
+
req->cb = cb;
|
386
|
+
memset(&req->overlapped, 0, sizeof(req->overlapped));
|
387
|
+
|
388
|
+
result = WSASendTo(handle->socket,
|
389
|
+
(WSABUF*)bufs,
|
390
|
+
bufcnt,
|
391
|
+
&bytes,
|
392
|
+
0,
|
393
|
+
addr,
|
394
|
+
addr_len,
|
395
|
+
&req->overlapped,
|
396
|
+
NULL);
|
397
|
+
|
398
|
+
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
|
399
|
+
/* Request completed immediately. */
|
400
|
+
req->queued_bytes = 0;
|
401
|
+
handle->reqs_pending++;
|
402
|
+
uv_ref(loop);
|
403
|
+
uv_insert_pending_req(loop, (uv_req_t*)req);
|
404
|
+
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
405
|
+
/* Request queued by the kernel. */
|
406
|
+
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
|
407
|
+
handle->reqs_pending++;
|
408
|
+
uv_ref(loop);
|
409
|
+
} else {
|
410
|
+
/* Send failed due to an error. */
|
411
|
+
uv__set_sys_error(loop, WSAGetLastError());
|
412
|
+
return -1;
|
413
|
+
}
|
414
|
+
|
415
|
+
return 0;
|
416
|
+
}
|
417
|
+
|
418
|
+
|
419
|
+
int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
|
420
|
+
int bufcnt, struct sockaddr_in addr, uv_udp_send_cb cb) {
|
421
|
+
|
422
|
+
if (!(handle->flags & UV_HANDLE_BOUND) &&
|
423
|
+
uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) {
|
424
|
+
return -1;
|
425
|
+
}
|
426
|
+
|
427
|
+
return uv__udp_send(req,
|
428
|
+
handle,
|
429
|
+
bufs,
|
430
|
+
bufcnt,
|
431
|
+
(struct sockaddr*) &addr,
|
432
|
+
sizeof addr,
|
433
|
+
cb);
|
434
|
+
}
|
435
|
+
|
436
|
+
|
437
|
+
int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
|
438
|
+
int bufcnt, struct sockaddr_in6 addr, uv_udp_send_cb cb) {
|
439
|
+
|
440
|
+
if (!(handle->flags & UV_HANDLE_BOUND) &&
|
441
|
+
uv_udp_bind6(handle, uv_addr_ip6_any_, 0) < 0) {
|
442
|
+
return -1;
|
443
|
+
}
|
444
|
+
|
445
|
+
return uv__udp_send(req,
|
446
|
+
handle,
|
447
|
+
bufs,
|
448
|
+
bufcnt,
|
449
|
+
(struct sockaddr*) &addr,
|
450
|
+
sizeof addr,
|
451
|
+
cb);
|
452
|
+
}
|
453
|
+
|
454
|
+
|
455
|
+
void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
|
456
|
+
uv_req_t* req) {
|
457
|
+
uv_buf_t buf;
|
458
|
+
int partial;
|
459
|
+
|
460
|
+
assert(handle->type == UV_UDP);
|
461
|
+
|
462
|
+
handle->flags &= ~UV_HANDLE_READ_PENDING;
|
463
|
+
|
464
|
+
if (!REQ_SUCCESS(req)) {
|
465
|
+
DWORD err = GET_REQ_SOCK_ERROR(req);
|
466
|
+
if (err == WSAEMSGSIZE) {
|
467
|
+
/* Not a real error, it just indicates that the received packet */
|
468
|
+
/* was bigger than the receive buffer. */
|
469
|
+
} else if (err == WSAECONNRESET || err == WSAENETRESET) {
|
470
|
+
/* A previous sendto operation failed; ignore this error. If */
|
471
|
+
/* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */
|
472
|
+
/* MSG_PEEK flag to clear out the error queue. For nonzero reads, */
|
473
|
+
/* immediately queue a new receive. */
|
474
|
+
if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
|
475
|
+
goto done;
|
476
|
+
}
|
477
|
+
} else {
|
478
|
+
/* A real error occurred. Report the error to the user only if we're */
|
479
|
+
/* currently reading. */
|
480
|
+
if (handle->flags & UV_HANDLE_READING) {
|
481
|
+
uv__set_sys_error(loop, err);
|
482
|
+
uv_udp_recv_stop(handle);
|
483
|
+
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
|
484
|
+
uv_buf_init(NULL, 0) : handle->recv_buffer;
|
485
|
+
handle->recv_cb(handle, -1, buf, NULL, 0);
|
486
|
+
}
|
487
|
+
goto done;
|
488
|
+
}
|
489
|
+
}
|
490
|
+
|
491
|
+
if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
|
492
|
+
/* Successful read */
|
493
|
+
partial = !REQ_SUCCESS(req);
|
494
|
+
handle->recv_cb(handle,
|
495
|
+
req->overlapped.InternalHigh,
|
496
|
+
handle->recv_buffer,
|
497
|
+
(struct sockaddr*) &handle->recv_from,
|
498
|
+
partial ? UV_UDP_PARTIAL : 0);
|
499
|
+
} else if (handle->flags & UV_HANDLE_READING) {
|
500
|
+
DWORD bytes, err, flags;
|
501
|
+
struct sockaddr_storage from;
|
502
|
+
int from_len;
|
503
|
+
|
504
|
+
/* Do a nonblocking receive */
|
505
|
+
/* TODO: try to read multiple datagrams at once. FIONREAD maybe? */
|
506
|
+
buf = handle->alloc_cb((uv_handle_t*) handle, 65536);
|
507
|
+
assert(buf.len > 0);
|
508
|
+
|
509
|
+
memset(&from, 0, sizeof from);
|
510
|
+
from_len = sizeof from;
|
511
|
+
|
512
|
+
flags = 0;
|
513
|
+
|
514
|
+
if (WSARecvFrom(handle->socket,
|
515
|
+
(WSABUF*)&buf,
|
516
|
+
1,
|
517
|
+
&bytes,
|
518
|
+
&flags,
|
519
|
+
(struct sockaddr*) &from,
|
520
|
+
&from_len,
|
521
|
+
NULL,
|
522
|
+
NULL) != SOCKET_ERROR) {
|
523
|
+
|
524
|
+
/* Message received */
|
525
|
+
handle->recv_cb(handle, bytes, buf, (struct sockaddr*) &from, 0);
|
526
|
+
} else {
|
527
|
+
err = WSAGetLastError();
|
528
|
+
if (err == WSAEMSGSIZE) {
|
529
|
+
/* Message truncated */
|
530
|
+
handle->recv_cb(handle,
|
531
|
+
bytes,
|
532
|
+
buf,
|
533
|
+
(struct sockaddr*) &from,
|
534
|
+
UV_UDP_PARTIAL);
|
535
|
+
} if (err == WSAEWOULDBLOCK) {
|
536
|
+
/* Kernel buffer empty */
|
537
|
+
uv__set_sys_error(loop, WSAEWOULDBLOCK);
|
538
|
+
handle->recv_cb(handle, 0, buf, NULL, 0);
|
539
|
+
} else if (err != WSAECONNRESET && err != WSAENETRESET) {
|
540
|
+
/* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */
|
541
|
+
/* just indicates that a previous sendto operation failed. */
|
542
|
+
uv_udp_recv_stop(handle);
|
543
|
+
uv__set_sys_error(loop, err);
|
544
|
+
handle->recv_cb(handle, -1, buf, NULL, 0);
|
545
|
+
}
|
546
|
+
}
|
547
|
+
}
|
548
|
+
|
549
|
+
done:
|
550
|
+
/* Post another read if still reading and not closing. */
|
551
|
+
if ((handle->flags & UV_HANDLE_READING) &&
|
552
|
+
!(handle->flags & UV_HANDLE_READ_PENDING)) {
|
553
|
+
uv_udp_queue_recv(loop, handle);
|
554
|
+
}
|
555
|
+
|
556
|
+
DECREASE_PENDING_REQ_COUNT(handle);
|
557
|
+
}
|
558
|
+
|
559
|
+
|
560
|
+
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
|
561
|
+
uv_udp_send_t* req) {
|
562
|
+
assert(handle->type == UV_UDP);
|
563
|
+
|
564
|
+
if (req->cb) {
|
565
|
+
if (REQ_SUCCESS(req)) {
|
566
|
+
req->cb(req, 0);
|
567
|
+
} else {
|
568
|
+
uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
|
569
|
+
req->cb(req, -1);
|
570
|
+
}
|
571
|
+
}
|
572
|
+
|
573
|
+
uv_unref(loop);
|
574
|
+
DECREASE_PENDING_REQ_COUNT(handle);
|
575
|
+
}
|
576
|
+
|
577
|
+
|
578
|
+
int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
|
579
|
+
const char* interface_addr, uv_membership membership) {
|
580
|
+
int optname;
|
581
|
+
struct ip_mreq mreq;
|
582
|
+
|
583
|
+
/* If the socket is unbound, bind to inaddr_any. */
|
584
|
+
if (!(handle->flags & UV_HANDLE_BOUND) &&
|
585
|
+
uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) {
|
586
|
+
return -1;
|
587
|
+
}
|
588
|
+
|
589
|
+
if (handle->flags & UV_HANDLE_IPV6) {
|
590
|
+
uv__set_artificial_error(handle->loop, UV_ENOSYS);
|
591
|
+
return -1;
|
592
|
+
}
|
593
|
+
|
594
|
+
memset(&mreq, 0, sizeof mreq);
|
595
|
+
|
596
|
+
if (interface_addr) {
|
597
|
+
mreq.imr_interface.s_addr = inet_addr(interface_addr);
|
598
|
+
} else {
|
599
|
+
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
600
|
+
}
|
601
|
+
|
602
|
+
mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
|
603
|
+
|
604
|
+
switch (membership) {
|
605
|
+
case UV_JOIN_GROUP:
|
606
|
+
optname = IP_ADD_MEMBERSHIP;
|
607
|
+
break;
|
608
|
+
case UV_LEAVE_GROUP:
|
609
|
+
optname = IP_DROP_MEMBERSHIP;
|
610
|
+
break;
|
611
|
+
default:
|
612
|
+
uv__set_artificial_error(handle->loop, UV_EFAULT);
|
613
|
+
return -1;
|
614
|
+
}
|
615
|
+
|
616
|
+
if (setsockopt(handle->socket,
|
617
|
+
IPPROTO_IP,
|
618
|
+
optname,
|
619
|
+
(char*) &mreq,
|
620
|
+
sizeof mreq) == SOCKET_ERROR) {
|
621
|
+
uv__set_sys_error(handle->loop, WSAGetLastError());
|
622
|
+
return -1;
|
623
|
+
}
|
624
|
+
|
625
|
+
return 0;
|
626
|
+
}
|
627
|
+
|
628
|
+
|
629
|
+
int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
|
630
|
+
BOOL optval = (BOOL) value;
|
631
|
+
|
632
|
+
/* If the socket is unbound, bind to inaddr_any. */
|
633
|
+
if (!(handle->flags & UV_HANDLE_BOUND) &&
|
634
|
+
uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) {
|
635
|
+
return -1;
|
636
|
+
}
|
637
|
+
|
638
|
+
if (setsockopt(handle->socket,
|
639
|
+
SOL_SOCKET,
|
640
|
+
SO_BROADCAST,
|
641
|
+
(char*) &optval,
|
642
|
+
sizeof optval)) {
|
643
|
+
uv__set_sys_error(handle->loop, WSAGetLastError());
|
644
|
+
return -1;
|
645
|
+
}
|
646
|
+
return 0;
|
647
|
+
}
|
648
|
+
|
649
|
+
|
650
|
+
#define SOCKOPT_SETTER(name, option4, option6, validate) \
|
651
|
+
int uv_udp_set_##name(uv_udp_t* handle, int value) { \
|
652
|
+
DWORD optval = (DWORD) value; \
|
653
|
+
\
|
654
|
+
if (!(validate(value))) { \
|
655
|
+
uv__set_artificial_error(handle->loop, UV_EINVAL); \
|
656
|
+
return -1; \
|
657
|
+
} \
|
658
|
+
\
|
659
|
+
/* If the socket is unbound, bind to inaddr_any. */ \
|
660
|
+
if (!(handle->flags & UV_HANDLE_BOUND) && \
|
661
|
+
uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) { \
|
662
|
+
return -1; \
|
663
|
+
} \
|
664
|
+
\
|
665
|
+
if (!(handle->flags & UV_HANDLE_IPV6)) { \
|
666
|
+
/* Set IPv4 socket option */ \
|
667
|
+
if (setsockopt(handle->socket, \
|
668
|
+
IPPROTO_IP, \
|
669
|
+
option4, \
|
670
|
+
(char*) &optval, \
|
671
|
+
sizeof optval)) { \
|
672
|
+
uv__set_sys_error(handle->loop, WSAGetLastError()); \
|
673
|
+
return -1; \
|
674
|
+
} \
|
675
|
+
} else { \
|
676
|
+
/* Set IPv6 socket option */ \
|
677
|
+
if (setsockopt(handle->socket, \
|
678
|
+
IPPROTO_IPV6, \
|
679
|
+
option6, \
|
680
|
+
(char*) &optval, \
|
681
|
+
sizeof optval)) { \
|
682
|
+
uv__set_sys_error(handle->loop, WSAGetLastError()); \
|
683
|
+
return -1; \
|
684
|
+
} \
|
685
|
+
} \
|
686
|
+
return 0; \
|
687
|
+
}
|
688
|
+
|
689
|
+
#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255)
|
690
|
+
#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255)
|
691
|
+
#define VALIDATE_MULTICAST_LOOP(value) (1)
|
692
|
+
|
693
|
+
SOCKOPT_SETTER(ttl,
|
694
|
+
IP_TTL,
|
695
|
+
IPV6_HOPLIMIT,
|
696
|
+
VALIDATE_TTL)
|
697
|
+
SOCKOPT_SETTER(multicast_ttl,
|
698
|
+
IP_MULTICAST_TTL,
|
699
|
+
IPV6_MULTICAST_HOPS,
|
700
|
+
VALIDATE_MULTICAST_TTL)
|
701
|
+
SOCKOPT_SETTER(multicast_loop,
|
702
|
+
IP_MULTICAST_LOOP,
|
703
|
+
IPV6_MULTICAST_LOOP,
|
704
|
+
VALIDATE_MULTICAST_LOOP)
|
705
|
+
|
706
|
+
#undef SOCKOPT_SETTER
|
707
|
+
#undef VALIDATE_TTL
|
708
|
+
#undef VALIDATE_MULTICAST_TTL
|
709
|
+
#undef VALIDATE_MULTICAST_LOOP
|