@point3/node-rdkafka 3.6.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (707) hide show
  1. package/LICENSE.txt +20 -0
  2. package/README.md +636 -0
  3. package/binding.gyp +154 -0
  4. package/deps/librdkafka/.clang-format +136 -0
  5. package/deps/librdkafka/.clang-format-cpp +103 -0
  6. package/deps/librdkafka/.dir-locals.el +10 -0
  7. package/deps/librdkafka/.formatignore +33 -0
  8. package/deps/librdkafka/.gdbmacros +19 -0
  9. package/deps/librdkafka/.github/CODEOWNERS +1 -0
  10. package/deps/librdkafka/.github/ISSUE_TEMPLATE +34 -0
  11. package/deps/librdkafka/.semaphore/run-all-tests.yml +77 -0
  12. package/deps/librdkafka/.semaphore/semaphore-integration.yml +250 -0
  13. package/deps/librdkafka/.semaphore/semaphore.yml +378 -0
  14. package/deps/librdkafka/.semaphore/verify-linux-packages.yml +41 -0
  15. package/deps/librdkafka/CHANGELOG.md +2208 -0
  16. package/deps/librdkafka/CMakeLists.txt +291 -0
  17. package/deps/librdkafka/CODE_OF_CONDUCT.md +46 -0
  18. package/deps/librdkafka/CONFIGURATION.md +209 -0
  19. package/deps/librdkafka/CONTRIBUTING.md +431 -0
  20. package/deps/librdkafka/Doxyfile +2375 -0
  21. package/deps/librdkafka/INTRODUCTION.md +2481 -0
  22. package/deps/librdkafka/LICENSE +26 -0
  23. package/deps/librdkafka/LICENSE.cjson +22 -0
  24. package/deps/librdkafka/LICENSE.crc32c +28 -0
  25. package/deps/librdkafka/LICENSE.fnv1a +18 -0
  26. package/deps/librdkafka/LICENSE.hdrhistogram +27 -0
  27. package/deps/librdkafka/LICENSE.lz4 +26 -0
  28. package/deps/librdkafka/LICENSE.murmur2 +25 -0
  29. package/deps/librdkafka/LICENSE.nanopb +22 -0
  30. package/deps/librdkafka/LICENSE.opentelemetry +203 -0
  31. package/deps/librdkafka/LICENSE.pycrc +23 -0
  32. package/deps/librdkafka/LICENSE.queue +31 -0
  33. package/deps/librdkafka/LICENSE.regexp +5 -0
  34. package/deps/librdkafka/LICENSE.snappy +36 -0
  35. package/deps/librdkafka/LICENSE.tinycthread +26 -0
  36. package/deps/librdkafka/LICENSE.wingetopt +49 -0
  37. package/deps/librdkafka/LICENSES.txt +625 -0
  38. package/deps/librdkafka/Makefile +125 -0
  39. package/deps/librdkafka/README.md +199 -0
  40. package/deps/librdkafka/README.win32 +26 -0
  41. package/deps/librdkafka/STATISTICS.md +624 -0
  42. package/deps/librdkafka/configure +214 -0
  43. package/deps/librdkafka/configure.self +331 -0
  44. package/deps/librdkafka/debian/changelog +111 -0
  45. package/deps/librdkafka/debian/compat +1 -0
  46. package/deps/librdkafka/debian/control +71 -0
  47. package/deps/librdkafka/debian/copyright +99 -0
  48. package/deps/librdkafka/debian/gbp.conf +9 -0
  49. package/deps/librdkafka/debian/librdkafka++1.install +1 -0
  50. package/deps/librdkafka/debian/librdkafka-dev.examples +2 -0
  51. package/deps/librdkafka/debian/librdkafka-dev.install +9 -0
  52. package/deps/librdkafka/debian/librdkafka1.docs +5 -0
  53. package/deps/librdkafka/debian/librdkafka1.install +1 -0
  54. package/deps/librdkafka/debian/librdkafka1.symbols +135 -0
  55. package/deps/librdkafka/debian/rules +19 -0
  56. package/deps/librdkafka/debian/source/format +1 -0
  57. package/deps/librdkafka/debian/watch +2 -0
  58. package/deps/librdkafka/dev-conf.sh +123 -0
  59. package/deps/librdkafka/examples/CMakeLists.txt +79 -0
  60. package/deps/librdkafka/examples/Makefile +167 -0
  61. package/deps/librdkafka/examples/README.md +42 -0
  62. package/deps/librdkafka/examples/alter_consumer_group_offsets.c +338 -0
  63. package/deps/librdkafka/examples/consumer.c +271 -0
  64. package/deps/librdkafka/examples/delete_records.c +233 -0
  65. package/deps/librdkafka/examples/describe_cluster.c +322 -0
  66. package/deps/librdkafka/examples/describe_consumer_groups.c +455 -0
  67. package/deps/librdkafka/examples/describe_topics.c +427 -0
  68. package/deps/librdkafka/examples/elect_leaders.c +317 -0
  69. package/deps/librdkafka/examples/globals.json +11 -0
  70. package/deps/librdkafka/examples/idempotent_producer.c +344 -0
  71. package/deps/librdkafka/examples/incremental_alter_configs.c +347 -0
  72. package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +945 -0
  73. package/deps/librdkafka/examples/list_consumer_group_offsets.c +359 -0
  74. package/deps/librdkafka/examples/list_consumer_groups.c +365 -0
  75. package/deps/librdkafka/examples/list_offsets.c +327 -0
  76. package/deps/librdkafka/examples/misc.c +287 -0
  77. package/deps/librdkafka/examples/openssl_engine_example.cpp +248 -0
  78. package/deps/librdkafka/examples/producer.c +251 -0
  79. package/deps/librdkafka/examples/producer.cpp +228 -0
  80. package/deps/librdkafka/examples/rdkafka_complex_consumer_example.c +617 -0
  81. package/deps/librdkafka/examples/rdkafka_complex_consumer_example.cpp +467 -0
  82. package/deps/librdkafka/examples/rdkafka_consume_batch.cpp +264 -0
  83. package/deps/librdkafka/examples/rdkafka_example.c +853 -0
  84. package/deps/librdkafka/examples/rdkafka_example.cpp +679 -0
  85. package/deps/librdkafka/examples/rdkafka_performance.c +1781 -0
  86. package/deps/librdkafka/examples/transactions-older-broker.c +668 -0
  87. package/deps/librdkafka/examples/transactions.c +665 -0
  88. package/deps/librdkafka/examples/user_scram.c +491 -0
  89. package/deps/librdkafka/examples/win_ssl_cert_store.cpp +396 -0
  90. package/deps/librdkafka/lds-gen.py +73 -0
  91. package/deps/librdkafka/mainpage.doxy +40 -0
  92. package/deps/librdkafka/mklove/Makefile.base +329 -0
  93. package/deps/librdkafka/mklove/modules/configure.atomics +144 -0
  94. package/deps/librdkafka/mklove/modules/configure.base +2484 -0
  95. package/deps/librdkafka/mklove/modules/configure.builtin +70 -0
  96. package/deps/librdkafka/mklove/modules/configure.cc +186 -0
  97. package/deps/librdkafka/mklove/modules/configure.cxx +8 -0
  98. package/deps/librdkafka/mklove/modules/configure.fileversion +65 -0
  99. package/deps/librdkafka/mklove/modules/configure.gitversion +29 -0
  100. package/deps/librdkafka/mklove/modules/configure.good_cflags +18 -0
  101. package/deps/librdkafka/mklove/modules/configure.host +132 -0
  102. package/deps/librdkafka/mklove/modules/configure.lib +49 -0
  103. package/deps/librdkafka/mklove/modules/configure.libcurl +99 -0
  104. package/deps/librdkafka/mklove/modules/configure.libsasl2 +36 -0
  105. package/deps/librdkafka/mklove/modules/configure.libssl +147 -0
  106. package/deps/librdkafka/mklove/modules/configure.libzstd +58 -0
  107. package/deps/librdkafka/mklove/modules/configure.parseversion +95 -0
  108. package/deps/librdkafka/mklove/modules/configure.pic +16 -0
  109. package/deps/librdkafka/mklove/modules/configure.socket +20 -0
  110. package/deps/librdkafka/mklove/modules/configure.zlib +61 -0
  111. package/deps/librdkafka/mklove/modules/patches/README.md +8 -0
  112. package/deps/librdkafka/mklove/modules/patches/libcurl.0000-no-runtime-linking-check.patch +11 -0
  113. package/deps/librdkafka/mklove/modules/patches/libssl.0000-osx-rand-include-fix-OpenSSL-PR16409.patch +56 -0
  114. package/deps/librdkafka/packaging/RELEASE.md +319 -0
  115. package/deps/librdkafka/packaging/alpine/build-alpine.sh +38 -0
  116. package/deps/librdkafka/packaging/archlinux/PKGBUILD +30 -0
  117. package/deps/librdkafka/packaging/cmake/Config.cmake.in +37 -0
  118. package/deps/librdkafka/packaging/cmake/Modules/FindLZ4.cmake +38 -0
  119. package/deps/librdkafka/packaging/cmake/Modules/FindZSTD.cmake +27 -0
  120. package/deps/librdkafka/packaging/cmake/Modules/LICENSE.FindZstd +178 -0
  121. package/deps/librdkafka/packaging/cmake/README.md +38 -0
  122. package/deps/librdkafka/packaging/cmake/config.h.in +52 -0
  123. package/deps/librdkafka/packaging/cmake/parseversion.cmake +60 -0
  124. package/deps/librdkafka/packaging/cmake/rdkafka.pc.in +12 -0
  125. package/deps/librdkafka/packaging/cmake/try_compile/atomic_32_test.c +8 -0
  126. package/deps/librdkafka/packaging/cmake/try_compile/atomic_64_test.c +8 -0
  127. package/deps/librdkafka/packaging/cmake/try_compile/c11threads_test.c +14 -0
  128. package/deps/librdkafka/packaging/cmake/try_compile/crc32c_hw_test.c +27 -0
  129. package/deps/librdkafka/packaging/cmake/try_compile/dlopen_test.c +11 -0
  130. package/deps/librdkafka/packaging/cmake/try_compile/libsasl2_test.c +7 -0
  131. package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_darwin_test.c +6 -0
  132. package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_freebsd_test.c +7 -0
  133. package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_gnu_test.c +5 -0
  134. package/deps/librdkafka/packaging/cmake/try_compile/rand_r_test.c +7 -0
  135. package/deps/librdkafka/packaging/cmake/try_compile/rdkafka_setup.cmake +122 -0
  136. package/deps/librdkafka/packaging/cmake/try_compile/regex_test.c +10 -0
  137. package/deps/librdkafka/packaging/cmake/try_compile/strndup_test.c +5 -0
  138. package/deps/librdkafka/packaging/cmake/try_compile/sync_32_test.c +8 -0
  139. package/deps/librdkafka/packaging/cmake/try_compile/sync_64_test.c +8 -0
  140. package/deps/librdkafka/packaging/cp/README.md +16 -0
  141. package/deps/librdkafka/packaging/cp/check_features.c +72 -0
  142. package/deps/librdkafka/packaging/cp/verify-deb.sh +33 -0
  143. package/deps/librdkafka/packaging/cp/verify-packages.sh +69 -0
  144. package/deps/librdkafka/packaging/cp/verify-rpm.sh +32 -0
  145. package/deps/librdkafka/packaging/debian/changelog +66 -0
  146. package/deps/librdkafka/packaging/debian/compat +1 -0
  147. package/deps/librdkafka/packaging/debian/control +49 -0
  148. package/deps/librdkafka/packaging/debian/copyright +84 -0
  149. package/deps/librdkafka/packaging/debian/docs +5 -0
  150. package/deps/librdkafka/packaging/debian/gbp.conf +9 -0
  151. package/deps/librdkafka/packaging/debian/librdkafka-dev.dirs +2 -0
  152. package/deps/librdkafka/packaging/debian/librdkafka-dev.examples +2 -0
  153. package/deps/librdkafka/packaging/debian/librdkafka-dev.install +6 -0
  154. package/deps/librdkafka/packaging/debian/librdkafka-dev.substvars +1 -0
  155. package/deps/librdkafka/packaging/debian/librdkafka.dsc +16 -0
  156. package/deps/librdkafka/packaging/debian/librdkafka1-dbg.substvars +1 -0
  157. package/deps/librdkafka/packaging/debian/librdkafka1.dirs +1 -0
  158. package/deps/librdkafka/packaging/debian/librdkafka1.install +2 -0
  159. package/deps/librdkafka/packaging/debian/librdkafka1.postinst.debhelper +5 -0
  160. package/deps/librdkafka/packaging/debian/librdkafka1.postrm.debhelper +5 -0
  161. package/deps/librdkafka/packaging/debian/librdkafka1.symbols +64 -0
  162. package/deps/librdkafka/packaging/debian/rules +19 -0
  163. package/deps/librdkafka/packaging/debian/source/format +1 -0
  164. package/deps/librdkafka/packaging/debian/watch +2 -0
  165. package/deps/librdkafka/packaging/get_version.py +21 -0
  166. package/deps/librdkafka/packaging/homebrew/README.md +15 -0
  167. package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +31 -0
  168. package/deps/librdkafka/packaging/mingw-w64/configure-build-msys2-mingw-static.sh +52 -0
  169. package/deps/librdkafka/packaging/mingw-w64/configure-build-msys2-mingw.sh +21 -0
  170. package/deps/librdkafka/packaging/mingw-w64/export-variables.sh +13 -0
  171. package/deps/librdkafka/packaging/mingw-w64/run-tests.sh +6 -0
  172. package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +38 -0
  173. package/deps/librdkafka/packaging/nuget/README.md +84 -0
  174. package/deps/librdkafka/packaging/nuget/artifact.py +177 -0
  175. package/deps/librdkafka/packaging/nuget/cleanup-s3.py +143 -0
  176. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-win32__bldtype-Release/msvcr120.zip +0 -0
  177. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-win32__bldtype-Release/msvcr140.zip +0 -0
  178. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-x64__bldtype-Release/msvcr120.zip +0 -0
  179. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-x64__bldtype-Release/msvcr140.zip +0 -0
  180. package/deps/librdkafka/packaging/nuget/nuget.sh +21 -0
  181. package/deps/librdkafka/packaging/nuget/nugetpackage.py +278 -0
  182. package/deps/librdkafka/packaging/nuget/packaging.py +448 -0
  183. package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +21 -0
  184. package/deps/librdkafka/packaging/nuget/release.py +167 -0
  185. package/deps/librdkafka/packaging/nuget/requirements.txt +3 -0
  186. package/deps/librdkafka/packaging/nuget/staticpackage.py +178 -0
  187. package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.nuspec +21 -0
  188. package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.props +18 -0
  189. package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.targets +19 -0
  190. package/deps/librdkafka/packaging/nuget/zfile/__init__.py +0 -0
  191. package/deps/librdkafka/packaging/nuget/zfile/zfile.py +98 -0
  192. package/deps/librdkafka/packaging/rpm/Makefile +92 -0
  193. package/deps/librdkafka/packaging/rpm/README.md +23 -0
  194. package/deps/librdkafka/packaging/rpm/el7-x86_64.cfg +40 -0
  195. package/deps/librdkafka/packaging/rpm/librdkafka.spec +118 -0
  196. package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +96 -0
  197. package/deps/librdkafka/packaging/rpm/tests/Makefile +25 -0
  198. package/deps/librdkafka/packaging/rpm/tests/README.md +8 -0
  199. package/deps/librdkafka/packaging/rpm/tests/run-test.sh +42 -0
  200. package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +56 -0
  201. package/deps/librdkafka/packaging/rpm/tests/test.c +77 -0
  202. package/deps/librdkafka/packaging/rpm/tests/test.cpp +34 -0
  203. package/deps/librdkafka/packaging/tools/Dockerfile +31 -0
  204. package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +12 -0
  205. package/deps/librdkafka/packaging/tools/build-deb-package.sh +64 -0
  206. package/deps/librdkafka/packaging/tools/build-debian.sh +65 -0
  207. package/deps/librdkafka/packaging/tools/build-manylinux.sh +68 -0
  208. package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +139 -0
  209. package/deps/librdkafka/packaging/tools/distro-build.sh +38 -0
  210. package/deps/librdkafka/packaging/tools/gh-release-checksums.py +39 -0
  211. package/deps/librdkafka/packaging/tools/rdutcoverage.sh +25 -0
  212. package/deps/librdkafka/packaging/tools/requirements.txt +2 -0
  213. package/deps/librdkafka/packaging/tools/run-in-docker.sh +28 -0
  214. package/deps/librdkafka/packaging/tools/run-integration-tests.sh +31 -0
  215. package/deps/librdkafka/packaging/tools/run-style-check.sh +4 -0
  216. package/deps/librdkafka/packaging/tools/style-format.sh +149 -0
  217. package/deps/librdkafka/packaging/tools/update_rpcs_max_versions.py +100 -0
  218. package/deps/librdkafka/service.yml +172 -0
  219. package/deps/librdkafka/src/CMakeLists.txt +374 -0
  220. package/deps/librdkafka/src/Makefile +103 -0
  221. package/deps/librdkafka/src/README.lz4.md +30 -0
  222. package/deps/librdkafka/src/cJSON.c +2834 -0
  223. package/deps/librdkafka/src/cJSON.h +398 -0
  224. package/deps/librdkafka/src/crc32c.c +430 -0
  225. package/deps/librdkafka/src/crc32c.h +38 -0
  226. package/deps/librdkafka/src/generate_proto.sh +66 -0
  227. package/deps/librdkafka/src/librdkafka_cgrp_synch.png +0 -0
  228. package/deps/librdkafka/src/lz4.c +2727 -0
  229. package/deps/librdkafka/src/lz4.h +842 -0
  230. package/deps/librdkafka/src/lz4frame.c +2078 -0
  231. package/deps/librdkafka/src/lz4frame.h +692 -0
  232. package/deps/librdkafka/src/lz4frame_static.h +47 -0
  233. package/deps/librdkafka/src/lz4hc.c +1631 -0
  234. package/deps/librdkafka/src/lz4hc.h +413 -0
  235. package/deps/librdkafka/src/nanopb/pb.h +917 -0
  236. package/deps/librdkafka/src/nanopb/pb_common.c +388 -0
  237. package/deps/librdkafka/src/nanopb/pb_common.h +49 -0
  238. package/deps/librdkafka/src/nanopb/pb_decode.c +1727 -0
  239. package/deps/librdkafka/src/nanopb/pb_decode.h +193 -0
  240. package/deps/librdkafka/src/nanopb/pb_encode.c +1000 -0
  241. package/deps/librdkafka/src/nanopb/pb_encode.h +185 -0
  242. package/deps/librdkafka/src/opentelemetry/common.pb.c +32 -0
  243. package/deps/librdkafka/src/opentelemetry/common.pb.h +170 -0
  244. package/deps/librdkafka/src/opentelemetry/metrics.options +2 -0
  245. package/deps/librdkafka/src/opentelemetry/metrics.pb.c +67 -0
  246. package/deps/librdkafka/src/opentelemetry/metrics.pb.h +966 -0
  247. package/deps/librdkafka/src/opentelemetry/resource.pb.c +12 -0
  248. package/deps/librdkafka/src/opentelemetry/resource.pb.h +58 -0
  249. package/deps/librdkafka/src/queue.h +850 -0
  250. package/deps/librdkafka/src/rd.h +584 -0
  251. package/deps/librdkafka/src/rdaddr.c +255 -0
  252. package/deps/librdkafka/src/rdaddr.h +202 -0
  253. package/deps/librdkafka/src/rdatomic.h +230 -0
  254. package/deps/librdkafka/src/rdavg.h +260 -0
  255. package/deps/librdkafka/src/rdavl.c +210 -0
  256. package/deps/librdkafka/src/rdavl.h +250 -0
  257. package/deps/librdkafka/src/rdbase64.c +200 -0
  258. package/deps/librdkafka/src/rdbase64.h +43 -0
  259. package/deps/librdkafka/src/rdbuf.c +1884 -0
  260. package/deps/librdkafka/src/rdbuf.h +375 -0
  261. package/deps/librdkafka/src/rdcrc32.c +114 -0
  262. package/deps/librdkafka/src/rdcrc32.h +170 -0
  263. package/deps/librdkafka/src/rddl.c +179 -0
  264. package/deps/librdkafka/src/rddl.h +43 -0
  265. package/deps/librdkafka/src/rdendian.h +175 -0
  266. package/deps/librdkafka/src/rdfloat.h +67 -0
  267. package/deps/librdkafka/src/rdfnv1a.c +113 -0
  268. package/deps/librdkafka/src/rdfnv1a.h +35 -0
  269. package/deps/librdkafka/src/rdgz.c +120 -0
  270. package/deps/librdkafka/src/rdgz.h +46 -0
  271. package/deps/librdkafka/src/rdhdrhistogram.c +721 -0
  272. package/deps/librdkafka/src/rdhdrhistogram.h +87 -0
  273. package/deps/librdkafka/src/rdhttp.c +830 -0
  274. package/deps/librdkafka/src/rdhttp.h +101 -0
  275. package/deps/librdkafka/src/rdinterval.h +177 -0
  276. package/deps/librdkafka/src/rdkafka.c +5505 -0
  277. package/deps/librdkafka/src/rdkafka.h +10686 -0
  278. package/deps/librdkafka/src/rdkafka_admin.c +9794 -0
  279. package/deps/librdkafka/src/rdkafka_admin.h +661 -0
  280. package/deps/librdkafka/src/rdkafka_assignment.c +1010 -0
  281. package/deps/librdkafka/src/rdkafka_assignment.h +73 -0
  282. package/deps/librdkafka/src/rdkafka_assignor.c +1786 -0
  283. package/deps/librdkafka/src/rdkafka_assignor.h +402 -0
  284. package/deps/librdkafka/src/rdkafka_aux.c +409 -0
  285. package/deps/librdkafka/src/rdkafka_aux.h +174 -0
  286. package/deps/librdkafka/src/rdkafka_background.c +221 -0
  287. package/deps/librdkafka/src/rdkafka_broker.c +6337 -0
  288. package/deps/librdkafka/src/rdkafka_broker.h +744 -0
  289. package/deps/librdkafka/src/rdkafka_buf.c +543 -0
  290. package/deps/librdkafka/src/rdkafka_buf.h +1525 -0
  291. package/deps/librdkafka/src/rdkafka_cert.c +576 -0
  292. package/deps/librdkafka/src/rdkafka_cert.h +62 -0
  293. package/deps/librdkafka/src/rdkafka_cgrp.c +7587 -0
  294. package/deps/librdkafka/src/rdkafka_cgrp.h +477 -0
  295. package/deps/librdkafka/src/rdkafka_conf.c +4880 -0
  296. package/deps/librdkafka/src/rdkafka_conf.h +732 -0
  297. package/deps/librdkafka/src/rdkafka_confval.h +97 -0
  298. package/deps/librdkafka/src/rdkafka_coord.c +623 -0
  299. package/deps/librdkafka/src/rdkafka_coord.h +132 -0
  300. package/deps/librdkafka/src/rdkafka_error.c +228 -0
  301. package/deps/librdkafka/src/rdkafka_error.h +80 -0
  302. package/deps/librdkafka/src/rdkafka_event.c +502 -0
  303. package/deps/librdkafka/src/rdkafka_event.h +126 -0
  304. package/deps/librdkafka/src/rdkafka_feature.c +898 -0
  305. package/deps/librdkafka/src/rdkafka_feature.h +104 -0
  306. package/deps/librdkafka/src/rdkafka_fetcher.c +1422 -0
  307. package/deps/librdkafka/src/rdkafka_fetcher.h +44 -0
  308. package/deps/librdkafka/src/rdkafka_header.c +220 -0
  309. package/deps/librdkafka/src/rdkafka_header.h +76 -0
  310. package/deps/librdkafka/src/rdkafka_idempotence.c +807 -0
  311. package/deps/librdkafka/src/rdkafka_idempotence.h +144 -0
  312. package/deps/librdkafka/src/rdkafka_int.h +1260 -0
  313. package/deps/librdkafka/src/rdkafka_interceptor.c +819 -0
  314. package/deps/librdkafka/src/rdkafka_interceptor.h +104 -0
  315. package/deps/librdkafka/src/rdkafka_lz4.c +450 -0
  316. package/deps/librdkafka/src/rdkafka_lz4.h +49 -0
  317. package/deps/librdkafka/src/rdkafka_metadata.c +2209 -0
  318. package/deps/librdkafka/src/rdkafka_metadata.h +345 -0
  319. package/deps/librdkafka/src/rdkafka_metadata_cache.c +1183 -0
  320. package/deps/librdkafka/src/rdkafka_mock.c +3661 -0
  321. package/deps/librdkafka/src/rdkafka_mock.h +610 -0
  322. package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1876 -0
  323. package/deps/librdkafka/src/rdkafka_mock_handlers.c +3113 -0
  324. package/deps/librdkafka/src/rdkafka_mock_int.h +710 -0
  325. package/deps/librdkafka/src/rdkafka_msg.c +2589 -0
  326. package/deps/librdkafka/src/rdkafka_msg.h +614 -0
  327. package/deps/librdkafka/src/rdkafka_msgbatch.h +62 -0
  328. package/deps/librdkafka/src/rdkafka_msgset.h +98 -0
  329. package/deps/librdkafka/src/rdkafka_msgset_reader.c +1806 -0
  330. package/deps/librdkafka/src/rdkafka_msgset_writer.c +1474 -0
  331. package/deps/librdkafka/src/rdkafka_offset.c +1565 -0
  332. package/deps/librdkafka/src/rdkafka_offset.h +150 -0
  333. package/deps/librdkafka/src/rdkafka_op.c +997 -0
  334. package/deps/librdkafka/src/rdkafka_op.h +858 -0
  335. package/deps/librdkafka/src/rdkafka_partition.c +4896 -0
  336. package/deps/librdkafka/src/rdkafka_partition.h +1182 -0
  337. package/deps/librdkafka/src/rdkafka_pattern.c +228 -0
  338. package/deps/librdkafka/src/rdkafka_pattern.h +70 -0
  339. package/deps/librdkafka/src/rdkafka_plugin.c +213 -0
  340. package/deps/librdkafka/src/rdkafka_plugin.h +41 -0
  341. package/deps/librdkafka/src/rdkafka_proto.h +736 -0
  342. package/deps/librdkafka/src/rdkafka_protocol.h +128 -0
  343. package/deps/librdkafka/src/rdkafka_queue.c +1230 -0
  344. package/deps/librdkafka/src/rdkafka_queue.h +1220 -0
  345. package/deps/librdkafka/src/rdkafka_range_assignor.c +1748 -0
  346. package/deps/librdkafka/src/rdkafka_request.c +7089 -0
  347. package/deps/librdkafka/src/rdkafka_request.h +732 -0
  348. package/deps/librdkafka/src/rdkafka_roundrobin_assignor.c +123 -0
  349. package/deps/librdkafka/src/rdkafka_sasl.c +530 -0
  350. package/deps/librdkafka/src/rdkafka_sasl.h +63 -0
  351. package/deps/librdkafka/src/rdkafka_sasl_cyrus.c +722 -0
  352. package/deps/librdkafka/src/rdkafka_sasl_int.h +89 -0
  353. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +1833 -0
  354. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.h +52 -0
  355. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1666 -0
  356. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +47 -0
  357. package/deps/librdkafka/src/rdkafka_sasl_plain.c +142 -0
  358. package/deps/librdkafka/src/rdkafka_sasl_scram.c +858 -0
  359. package/deps/librdkafka/src/rdkafka_sasl_win32.c +550 -0
  360. package/deps/librdkafka/src/rdkafka_ssl.c +2129 -0
  361. package/deps/librdkafka/src/rdkafka_ssl.h +86 -0
  362. package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4785 -0
  363. package/deps/librdkafka/src/rdkafka_subscription.c +278 -0
  364. package/deps/librdkafka/src/rdkafka_telemetry.c +760 -0
  365. package/deps/librdkafka/src/rdkafka_telemetry.h +52 -0
  366. package/deps/librdkafka/src/rdkafka_telemetry_decode.c +1053 -0
  367. package/deps/librdkafka/src/rdkafka_telemetry_decode.h +59 -0
  368. package/deps/librdkafka/src/rdkafka_telemetry_encode.c +997 -0
  369. package/deps/librdkafka/src/rdkafka_telemetry_encode.h +301 -0
  370. package/deps/librdkafka/src/rdkafka_timer.c +402 -0
  371. package/deps/librdkafka/src/rdkafka_timer.h +117 -0
  372. package/deps/librdkafka/src/rdkafka_topic.c +2161 -0
  373. package/deps/librdkafka/src/rdkafka_topic.h +334 -0
  374. package/deps/librdkafka/src/rdkafka_transport.c +1309 -0
  375. package/deps/librdkafka/src/rdkafka_transport.h +99 -0
  376. package/deps/librdkafka/src/rdkafka_transport_int.h +100 -0
  377. package/deps/librdkafka/src/rdkafka_txnmgr.c +3256 -0
  378. package/deps/librdkafka/src/rdkafka_txnmgr.h +171 -0
  379. package/deps/librdkafka/src/rdkafka_zstd.c +226 -0
  380. package/deps/librdkafka/src/rdkafka_zstd.h +57 -0
  381. package/deps/librdkafka/src/rdlist.c +576 -0
  382. package/deps/librdkafka/src/rdlist.h +434 -0
  383. package/deps/librdkafka/src/rdlog.c +89 -0
  384. package/deps/librdkafka/src/rdlog.h +41 -0
  385. package/deps/librdkafka/src/rdmap.c +508 -0
  386. package/deps/librdkafka/src/rdmap.h +492 -0
  387. package/deps/librdkafka/src/rdmurmur2.c +167 -0
  388. package/deps/librdkafka/src/rdmurmur2.h +35 -0
  389. package/deps/librdkafka/src/rdports.c +61 -0
  390. package/deps/librdkafka/src/rdports.h +38 -0
  391. package/deps/librdkafka/src/rdposix.h +250 -0
  392. package/deps/librdkafka/src/rdrand.c +80 -0
  393. package/deps/librdkafka/src/rdrand.h +43 -0
  394. package/deps/librdkafka/src/rdregex.c +156 -0
  395. package/deps/librdkafka/src/rdregex.h +43 -0
  396. package/deps/librdkafka/src/rdsignal.h +57 -0
  397. package/deps/librdkafka/src/rdstring.c +645 -0
  398. package/deps/librdkafka/src/rdstring.h +98 -0
  399. package/deps/librdkafka/src/rdsysqueue.h +404 -0
  400. package/deps/librdkafka/src/rdtime.h +356 -0
  401. package/deps/librdkafka/src/rdtypes.h +86 -0
  402. package/deps/librdkafka/src/rdunittest.c +549 -0
  403. package/deps/librdkafka/src/rdunittest.h +232 -0
  404. package/deps/librdkafka/src/rdvarint.c +134 -0
  405. package/deps/librdkafka/src/rdvarint.h +165 -0
  406. package/deps/librdkafka/src/rdwin32.h +382 -0
  407. package/deps/librdkafka/src/rdxxhash.c +1030 -0
  408. package/deps/librdkafka/src/rdxxhash.h +328 -0
  409. package/deps/librdkafka/src/regexp.c +1352 -0
  410. package/deps/librdkafka/src/regexp.h +41 -0
  411. package/deps/librdkafka/src/snappy.c +1866 -0
  412. package/deps/librdkafka/src/snappy.h +62 -0
  413. package/deps/librdkafka/src/snappy_compat.h +138 -0
  414. package/deps/librdkafka/src/statistics_schema.json +444 -0
  415. package/deps/librdkafka/src/tinycthread.c +932 -0
  416. package/deps/librdkafka/src/tinycthread.h +503 -0
  417. package/deps/librdkafka/src/tinycthread_extra.c +199 -0
  418. package/deps/librdkafka/src/tinycthread_extra.h +212 -0
  419. package/deps/librdkafka/src/win32_config.h +58 -0
  420. package/deps/librdkafka/src-cpp/CMakeLists.txt +90 -0
  421. package/deps/librdkafka/src-cpp/ConfImpl.cpp +84 -0
  422. package/deps/librdkafka/src-cpp/ConsumerImpl.cpp +244 -0
  423. package/deps/librdkafka/src-cpp/HandleImpl.cpp +436 -0
  424. package/deps/librdkafka/src-cpp/HeadersImpl.cpp +48 -0
  425. package/deps/librdkafka/src-cpp/KafkaConsumerImpl.cpp +296 -0
  426. package/deps/librdkafka/src-cpp/Makefile +55 -0
  427. package/deps/librdkafka/src-cpp/MessageImpl.cpp +38 -0
  428. package/deps/librdkafka/src-cpp/MetadataImpl.cpp +170 -0
  429. package/deps/librdkafka/src-cpp/ProducerImpl.cpp +197 -0
  430. package/deps/librdkafka/src-cpp/QueueImpl.cpp +70 -0
  431. package/deps/librdkafka/src-cpp/README.md +16 -0
  432. package/deps/librdkafka/src-cpp/RdKafka.cpp +59 -0
  433. package/deps/librdkafka/src-cpp/TopicImpl.cpp +124 -0
  434. package/deps/librdkafka/src-cpp/TopicPartitionImpl.cpp +57 -0
  435. package/deps/librdkafka/src-cpp/rdkafkacpp.h +3797 -0
  436. package/deps/librdkafka/src-cpp/rdkafkacpp_int.h +1641 -0
  437. package/deps/librdkafka/tests/0000-unittests.c +72 -0
  438. package/deps/librdkafka/tests/0001-multiobj.c +102 -0
  439. package/deps/librdkafka/tests/0002-unkpart.c +244 -0
  440. package/deps/librdkafka/tests/0003-msgmaxsize.c +173 -0
  441. package/deps/librdkafka/tests/0004-conf.c +934 -0
  442. package/deps/librdkafka/tests/0005-order.c +133 -0
  443. package/deps/librdkafka/tests/0006-symbols.c +163 -0
  444. package/deps/librdkafka/tests/0007-autotopic.c +136 -0
  445. package/deps/librdkafka/tests/0008-reqacks.c +179 -0
  446. package/deps/librdkafka/tests/0009-mock_cluster.c +97 -0
  447. package/deps/librdkafka/tests/0011-produce_batch.c +753 -0
  448. package/deps/librdkafka/tests/0012-produce_consume.c +537 -0
  449. package/deps/librdkafka/tests/0013-null-msgs.c +473 -0
  450. package/deps/librdkafka/tests/0014-reconsume-191.c +512 -0
  451. package/deps/librdkafka/tests/0015-offset_seeks.c +172 -0
  452. package/deps/librdkafka/tests/0016-client_swname.c +181 -0
  453. package/deps/librdkafka/tests/0017-compression.c +140 -0
  454. package/deps/librdkafka/tests/0018-cgrp_term.c +338 -0
  455. package/deps/librdkafka/tests/0019-list_groups.c +289 -0
  456. package/deps/librdkafka/tests/0020-destroy_hang.c +162 -0
  457. package/deps/librdkafka/tests/0021-rkt_destroy.c +72 -0
  458. package/deps/librdkafka/tests/0022-consume_batch.c +279 -0
  459. package/deps/librdkafka/tests/0025-timers.c +147 -0
  460. package/deps/librdkafka/tests/0026-consume_pause.c +547 -0
  461. package/deps/librdkafka/tests/0028-long_topicnames.c +79 -0
  462. package/deps/librdkafka/tests/0029-assign_offset.c +202 -0
  463. package/deps/librdkafka/tests/0030-offset_commit.c +589 -0
  464. package/deps/librdkafka/tests/0031-get_offsets.c +235 -0
  465. package/deps/librdkafka/tests/0033-regex_subscribe.c +536 -0
  466. package/deps/librdkafka/tests/0034-offset_reset.c +398 -0
  467. package/deps/librdkafka/tests/0035-api_version.c +73 -0
  468. package/deps/librdkafka/tests/0036-partial_fetch.c +87 -0
  469. package/deps/librdkafka/tests/0037-destroy_hang_local.c +85 -0
  470. package/deps/librdkafka/tests/0038-performance.c +121 -0
  471. package/deps/librdkafka/tests/0039-event.c +284 -0
  472. package/deps/librdkafka/tests/0040-io_event.c +257 -0
  473. package/deps/librdkafka/tests/0041-fetch_max_bytes.c +97 -0
  474. package/deps/librdkafka/tests/0042-many_topics.c +252 -0
  475. package/deps/librdkafka/tests/0043-no_connection.c +77 -0
  476. package/deps/librdkafka/tests/0044-partition_cnt.c +94 -0
  477. package/deps/librdkafka/tests/0045-subscribe_update.c +1010 -0
  478. package/deps/librdkafka/tests/0046-rkt_cache.c +65 -0
  479. package/deps/librdkafka/tests/0047-partial_buf_tmout.c +98 -0
  480. package/deps/librdkafka/tests/0048-partitioner.c +283 -0
  481. package/deps/librdkafka/tests/0049-consume_conn_close.c +162 -0
  482. package/deps/librdkafka/tests/0050-subscribe_adds.c +145 -0
  483. package/deps/librdkafka/tests/0051-assign_adds.c +126 -0
  484. package/deps/librdkafka/tests/0052-msg_timestamps.c +238 -0
  485. package/deps/librdkafka/tests/0053-stats_cb.cpp +527 -0
  486. package/deps/librdkafka/tests/0054-offset_time.cpp +236 -0
  487. package/deps/librdkafka/tests/0055-producer_latency.c +539 -0
  488. package/deps/librdkafka/tests/0056-balanced_group_mt.c +315 -0
  489. package/deps/librdkafka/tests/0057-invalid_topic.cpp +112 -0
  490. package/deps/librdkafka/tests/0058-log.cpp +123 -0
  491. package/deps/librdkafka/tests/0059-bsearch.cpp +241 -0
  492. package/deps/librdkafka/tests/0060-op_prio.cpp +163 -0
  493. package/deps/librdkafka/tests/0061-consumer_lag.cpp +295 -0
  494. package/deps/librdkafka/tests/0062-stats_event.c +126 -0
  495. package/deps/librdkafka/tests/0063-clusterid.cpp +180 -0
  496. package/deps/librdkafka/tests/0064-interceptors.c +481 -0
  497. package/deps/librdkafka/tests/0065-yield.cpp +140 -0
  498. package/deps/librdkafka/tests/0066-plugins.cpp +129 -0
  499. package/deps/librdkafka/tests/0067-empty_topic.cpp +151 -0
  500. package/deps/librdkafka/tests/0068-produce_timeout.c +136 -0
  501. package/deps/librdkafka/tests/0069-consumer_add_parts.c +119 -0
  502. package/deps/librdkafka/tests/0070-null_empty.cpp +197 -0
  503. package/deps/librdkafka/tests/0072-headers_ut.c +448 -0
  504. package/deps/librdkafka/tests/0073-headers.c +381 -0
  505. package/deps/librdkafka/tests/0074-producev.c +87 -0
  506. package/deps/librdkafka/tests/0075-retry.c +290 -0
  507. package/deps/librdkafka/tests/0076-produce_retry.c +452 -0
  508. package/deps/librdkafka/tests/0077-compaction.c +363 -0
  509. package/deps/librdkafka/tests/0078-c_from_cpp.cpp +96 -0
  510. package/deps/librdkafka/tests/0079-fork.c +93 -0
  511. package/deps/librdkafka/tests/0080-admin_ut.c +3095 -0
  512. package/deps/librdkafka/tests/0081-admin.c +5633 -0
  513. package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +137 -0
  514. package/deps/librdkafka/tests/0083-cb_event.c +233 -0
  515. package/deps/librdkafka/tests/0084-destroy_flags.c +208 -0
  516. package/deps/librdkafka/tests/0085-headers.cpp +392 -0
  517. package/deps/librdkafka/tests/0086-purge.c +368 -0
  518. package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +162 -0
  519. package/deps/librdkafka/tests/0089-max_poll_interval.c +511 -0
  520. package/deps/librdkafka/tests/0090-idempotence.c +171 -0
  521. package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +295 -0
  522. package/deps/librdkafka/tests/0092-mixed_msgver.c +103 -0
  523. package/deps/librdkafka/tests/0093-holb.c +200 -0
  524. package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +231 -0
  525. package/deps/librdkafka/tests/0095-all_brokers_down.cpp +122 -0
  526. package/deps/librdkafka/tests/0097-ssl_verify.cpp +658 -0
  527. package/deps/librdkafka/tests/0098-consumer-txn.cpp +1218 -0
  528. package/deps/librdkafka/tests/0099-commit_metadata.c +194 -0
  529. package/deps/librdkafka/tests/0100-thread_interceptors.cpp +195 -0
  530. package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +446 -0
  531. package/deps/librdkafka/tests/0102-static_group_rebalance.c +836 -0
  532. package/deps/librdkafka/tests/0103-transactions.c +1383 -0
  533. package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +625 -0
  534. package/deps/librdkafka/tests/0105-transactions_mock.c +3930 -0
  535. package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +318 -0
  536. package/deps/librdkafka/tests/0107-topic_recreate.c +259 -0
  537. package/deps/librdkafka/tests/0109-auto_create_topics.cpp +278 -0
  538. package/deps/librdkafka/tests/0110-batch_size.cpp +182 -0
  539. package/deps/librdkafka/tests/0111-delay_create_topics.cpp +127 -0
  540. package/deps/librdkafka/tests/0112-assign_unknown_part.c +87 -0
  541. package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +3473 -0
  542. package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +176 -0
  543. package/deps/librdkafka/tests/0115-producer_auth.cpp +182 -0
  544. package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +216 -0
  545. package/deps/librdkafka/tests/0117-mock_errors.c +331 -0
  546. package/deps/librdkafka/tests/0118-commit_rebalance.c +154 -0
  547. package/deps/librdkafka/tests/0119-consumer_auth.cpp +167 -0
  548. package/deps/librdkafka/tests/0120-asymmetric_subscription.c +185 -0
  549. package/deps/librdkafka/tests/0121-clusterid.c +115 -0
  550. package/deps/librdkafka/tests/0122-buffer_cleaning_after_rebalance.c +227 -0
  551. package/deps/librdkafka/tests/0123-connections_max_idle.c +98 -0
  552. package/deps/librdkafka/tests/0124-openssl_invalid_engine.c +69 -0
  553. package/deps/librdkafka/tests/0125-immediate_flush.c +144 -0
  554. package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +528 -0
  555. package/deps/librdkafka/tests/0127-fetch_queue_backoff.cpp +165 -0
  556. package/deps/librdkafka/tests/0128-sasl_callback_queue.cpp +125 -0
  557. package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +79 -0
  558. package/deps/librdkafka/tests/0130-store_offsets.c +178 -0
  559. package/deps/librdkafka/tests/0131-connect_timeout.c +81 -0
  560. package/deps/librdkafka/tests/0132-strategy_ordering.c +179 -0
  561. package/deps/librdkafka/tests/0133-ssl_keys.c +150 -0
  562. package/deps/librdkafka/tests/0134-ssl_provider.c +92 -0
  563. package/deps/librdkafka/tests/0135-sasl_credentials.cpp +143 -0
  564. package/deps/librdkafka/tests/0136-resolve_cb.c +181 -0
  565. package/deps/librdkafka/tests/0137-barrier_batch_consume.c +619 -0
  566. package/deps/librdkafka/tests/0138-admin_mock.c +281 -0
  567. package/deps/librdkafka/tests/0139-offset_validation_mock.c +950 -0
  568. package/deps/librdkafka/tests/0140-commit_metadata.cpp +108 -0
  569. package/deps/librdkafka/tests/0142-reauthentication.c +515 -0
  570. package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +552 -0
  571. package/deps/librdkafka/tests/0144-idempotence_mock.c +373 -0
  572. package/deps/librdkafka/tests/0145-pause_resume_mock.c +119 -0
  573. package/deps/librdkafka/tests/0146-metadata_mock.c +505 -0
  574. package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +952 -0
  575. package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +563 -0
  576. package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
  577. package/deps/librdkafka/tests/0150-telemetry_mock.c +651 -0
  578. package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
  579. package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
  580. package/deps/librdkafka/tests/0153-memberid.c +128 -0
  581. package/deps/librdkafka/tests/1000-unktopic.c +164 -0
  582. package/deps/librdkafka/tests/8000-idle.cpp +60 -0
  583. package/deps/librdkafka/tests/8001-fetch_from_follower_mock_manual.c +113 -0
  584. package/deps/librdkafka/tests/CMakeLists.txt +170 -0
  585. package/deps/librdkafka/tests/LibrdkafkaTestApp.py +291 -0
  586. package/deps/librdkafka/tests/Makefile +182 -0
  587. package/deps/librdkafka/tests/README.md +509 -0
  588. package/deps/librdkafka/tests/autotest.sh +33 -0
  589. package/deps/librdkafka/tests/backtrace.gdb +30 -0
  590. package/deps/librdkafka/tests/broker_version_tests.py +315 -0
  591. package/deps/librdkafka/tests/buildbox.sh +17 -0
  592. package/deps/librdkafka/tests/cleanup-checker-tests.sh +20 -0
  593. package/deps/librdkafka/tests/cluster_testing.py +191 -0
  594. package/deps/librdkafka/tests/delete-test-topics.sh +56 -0
  595. package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
  596. package/deps/librdkafka/tests/fixtures/ssl/Makefile +8 -0
  597. package/deps/librdkafka/tests/fixtures/ssl/README.md +13 -0
  598. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
  599. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
  600. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
  601. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +50 -0
  602. package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
  603. package/deps/librdkafka/tests/fixtures/ssl/client2.key +46 -0
  604. package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +168 -0
  605. package/deps/librdkafka/tests/fuzzers/Makefile +12 -0
  606. package/deps/librdkafka/tests/fuzzers/README.md +31 -0
  607. package/deps/librdkafka/tests/fuzzers/fuzz_regex.c +74 -0
  608. package/deps/librdkafka/tests/fuzzers/helpers.h +90 -0
  609. package/deps/librdkafka/tests/gen-ssl-certs.sh +165 -0
  610. package/deps/librdkafka/tests/interactive_broker_version.py +170 -0
  611. package/deps/librdkafka/tests/interceptor_test/CMakeLists.txt +16 -0
  612. package/deps/librdkafka/tests/interceptor_test/Makefile +22 -0
  613. package/deps/librdkafka/tests/interceptor_test/interceptor_test.c +314 -0
  614. package/deps/librdkafka/tests/interceptor_test/interceptor_test.h +54 -0
  615. package/deps/librdkafka/tests/java/IncrementalRebalanceCli.java +97 -0
  616. package/deps/librdkafka/tests/java/Makefile +13 -0
  617. package/deps/librdkafka/tests/java/Murmur2Cli.java +46 -0
  618. package/deps/librdkafka/tests/java/README.md +14 -0
  619. package/deps/librdkafka/tests/java/TransactionProducerCli.java +162 -0
  620. package/deps/librdkafka/tests/java/run-class.sh +11 -0
  621. package/deps/librdkafka/tests/librdkafka.suppressions +483 -0
  622. package/deps/librdkafka/tests/lz4_manual_test.sh +59 -0
  623. package/deps/librdkafka/tests/multi-broker-version-test.sh +50 -0
  624. package/deps/librdkafka/tests/parse-refcnt.sh +43 -0
  625. package/deps/librdkafka/tests/performance_plot.py +115 -0
  626. package/deps/librdkafka/tests/plugin_test/Makefile +19 -0
  627. package/deps/librdkafka/tests/plugin_test/plugin_test.c +58 -0
  628. package/deps/librdkafka/tests/requirements.txt +2 -0
  629. package/deps/librdkafka/tests/run-all-tests.sh +79 -0
  630. package/deps/librdkafka/tests/run-consumer-tests.sh +16 -0
  631. package/deps/librdkafka/tests/run-producer-tests.sh +16 -0
  632. package/deps/librdkafka/tests/run-test-batches.py +157 -0
  633. package/deps/librdkafka/tests/run-test.sh +140 -0
  634. package/deps/librdkafka/tests/rusage.c +249 -0
  635. package/deps/librdkafka/tests/sasl_test.py +289 -0
  636. package/deps/librdkafka/tests/scenarios/README.md +6 -0
  637. package/deps/librdkafka/tests/scenarios/ak23.json +6 -0
  638. package/deps/librdkafka/tests/scenarios/default.json +5 -0
  639. package/deps/librdkafka/tests/scenarios/noautocreate.json +5 -0
  640. package/deps/librdkafka/tests/sockem.c +801 -0
  641. package/deps/librdkafka/tests/sockem.h +85 -0
  642. package/deps/librdkafka/tests/sockem_ctrl.c +145 -0
  643. package/deps/librdkafka/tests/sockem_ctrl.h +61 -0
  644. package/deps/librdkafka/tests/test.c +7778 -0
  645. package/deps/librdkafka/tests/test.conf.example +27 -0
  646. package/deps/librdkafka/tests/test.h +1028 -0
  647. package/deps/librdkafka/tests/testcpp.cpp +131 -0
  648. package/deps/librdkafka/tests/testcpp.h +388 -0
  649. package/deps/librdkafka/tests/testshared.h +416 -0
  650. package/deps/librdkafka/tests/tools/README.md +4 -0
  651. package/deps/librdkafka/tests/tools/stats/README.md +21 -0
  652. package/deps/librdkafka/tests/tools/stats/filter.jq +42 -0
  653. package/deps/librdkafka/tests/tools/stats/graph.py +150 -0
  654. package/deps/librdkafka/tests/tools/stats/requirements.txt +3 -0
  655. package/deps/librdkafka/tests/tools/stats/to_csv.py +124 -0
  656. package/deps/librdkafka/tests/trivup/trivup-0.14.0.tar.gz +0 -0
  657. package/deps/librdkafka/tests/until-fail.sh +87 -0
  658. package/deps/librdkafka/tests/xxxx-assign_partition.c +122 -0
  659. package/deps/librdkafka/tests/xxxx-metadata.cpp +159 -0
  660. package/deps/librdkafka/vcpkg.json +23 -0
  661. package/deps/librdkafka/win32/README.md +5 -0
  662. package/deps/librdkafka/win32/build-package.bat +3 -0
  663. package/deps/librdkafka/win32/build.bat +19 -0
  664. package/deps/librdkafka/win32/common.vcxproj +84 -0
  665. package/deps/librdkafka/win32/interceptor_test/interceptor_test.vcxproj +87 -0
  666. package/deps/librdkafka/win32/librdkafka.autopkg.template +54 -0
  667. package/deps/librdkafka/win32/librdkafka.master.testing.targets +13 -0
  668. package/deps/librdkafka/win32/librdkafka.sln +226 -0
  669. package/deps/librdkafka/win32/librdkafka.vcxproj +276 -0
  670. package/deps/librdkafka/win32/librdkafkacpp/librdkafkacpp.vcxproj +104 -0
  671. package/deps/librdkafka/win32/msbuild.ps1 +15 -0
  672. package/deps/librdkafka/win32/openssl_engine_example/openssl_engine_example.vcxproj +132 -0
  673. package/deps/librdkafka/win32/package-zip.ps1 +46 -0
  674. package/deps/librdkafka/win32/packages/repositories.config +4 -0
  675. package/deps/librdkafka/win32/push-package.bat +4 -0
  676. package/deps/librdkafka/win32/rdkafka_complex_consumer_example_cpp/rdkafka_complex_consumer_example_cpp.vcxproj +67 -0
  677. package/deps/librdkafka/win32/rdkafka_example/rdkafka_example.vcxproj +97 -0
  678. package/deps/librdkafka/win32/rdkafka_performance/rdkafka_performance.vcxproj +97 -0
  679. package/deps/librdkafka/win32/setup-msys2.ps1 +47 -0
  680. package/deps/librdkafka/win32/setup-vcpkg.ps1 +34 -0
  681. package/deps/librdkafka/win32/tests/test.conf.example +25 -0
  682. package/deps/librdkafka/win32/tests/tests.vcxproj +253 -0
  683. package/deps/librdkafka/win32/win_ssl_cert_store/win_ssl_cert_store.vcxproj +132 -0
  684. package/deps/librdkafka/win32/wingetopt.c +564 -0
  685. package/deps/librdkafka/win32/wingetopt.h +101 -0
  686. package/deps/librdkafka/win32/wintime.h +33 -0
  687. package/deps/librdkafka.gyp +62 -0
  688. package/lib/admin.js +233 -0
  689. package/lib/client.js +573 -0
  690. package/lib/error.js +500 -0
  691. package/lib/index.js +34 -0
  692. package/lib/kafka-consumer-stream.js +397 -0
  693. package/lib/kafka-consumer.js +698 -0
  694. package/lib/producer/high-level-producer.js +323 -0
  695. package/lib/producer-stream.js +307 -0
  696. package/lib/producer.js +375 -0
  697. package/lib/tools/ref-counter.js +52 -0
  698. package/lib/topic-partition.js +88 -0
  699. package/lib/topic.js +42 -0
  700. package/lib/util.js +29 -0
  701. package/package.json +61 -0
  702. package/prebuilds/darwin-arm64/@point3+node-rdkafka.node +0 -0
  703. package/prebuilds/linux-x64/@point3+node-rdkafka.node +0 -0
  704. package/util/configure.js +30 -0
  705. package/util/get-env.js +6 -0
  706. package/util/test-compile.js +11 -0
  707. package/util/test-producer-delivery.js +100 -0
@@ -0,0 +1,1806 @@
1
+ /*
2
+ * librdkafka - Apache Kafka C library
3
+ *
4
+ * Copyright (c) 2017-2022, Magnus Edenhill
5
+ * 2023, Confluent Inc.
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the following disclaimer.
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ * POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+ /**
31
+ * @name MessageSet reader interface
32
+ *
33
+ * Parses FetchResponse for Messages
34
+ *
35
+ *
36
+ * @remark
37
+ * The broker may send partial messages, when this happens we bail out
38
+ * silently and keep the messages that we successfully parsed.
39
+ *
40
+ * "A Guide To The Kafka Protocol" states:
41
+ * "As an optimization the server is allowed to
42
+ * return a partial message at the end of the
43
+ * message set.
44
+ * Clients should handle this case."
45
+ *
46
+ * We're handling it by not passing the error upstream.
47
+ * This is why most err_parse: goto labels (that are called from buf parsing
48
+ * macros) suppress the error message and why log_decode_errors is off
49
+ * unless PROTOCOL debugging is enabled.
50
+ *
51
+ * When a FetchResponse contains multiple partitions, each partition's
52
+ * MessageSet may be partial, regardless of the other partitions.
53
+ * To make sure the next partition can be parsed, each partition parse
54
+ * uses its own sub-slice of only that partition's MessageSetSize length.
55
+ */
56
+
57
+ #include "rd.h"
58
+ #include "rdunittest.h"
59
+ #include "rdavl.h"
60
+ #include "rdlist.h"
61
+ #include "rdkafka_int.h"
62
+ #include "rdkafka_msg.h"
63
+ #include "rdkafka_msgset.h"
64
+ #include "rdkafka_topic.h"
65
+ #include "rdkafka_partition.h"
66
+ #include "rdkafka_header.h"
67
+ #include "rdkafka_lz4.h"
68
+
69
+ #include "rdvarint.h"
70
+ #include "crc32c.h"
71
+
72
+ #if WITH_ZLIB
73
+ #include "rdgz.h"
74
+ #endif
75
+ #if WITH_SNAPPY
76
+ #include "snappy.h"
77
+ #endif
78
+ #if WITH_ZSTD
79
+ #include "rdkafka_zstd.h"
80
+ #endif
81
+
82
+
83
+ static RD_INLINE int64_t
84
+ rd_kafka_aborted_txns_pop_offset(rd_kafka_aborted_txns_t *aborted_txns,
85
+ int64_t pid,
86
+ int64_t max_offset);
87
+ static RD_INLINE int64_t
88
+ rd_kafka_aborted_txns_get_offset(const rd_kafka_aborted_txns_t *aborted_txns,
89
+ int64_t pid);
90
+
91
+
92
+ struct msgset_v2_hdr {
93
+ int64_t BaseOffset;
94
+ int32_t Length;
95
+ int32_t PartitionLeaderEpoch;
96
+ int8_t MagicByte;
97
+ int32_t Crc;
98
+ int16_t Attributes;
99
+ int32_t LastOffsetDelta;
100
+ int64_t BaseTimestamp;
101
+ int64_t MaxTimestamp;
102
+ int64_t PID;
103
+ int16_t ProducerEpoch;
104
+ int32_t BaseSequence;
105
+ int32_t RecordCount;
106
+ };
107
+
108
+
109
+ /**
110
+ * @struct rd_kafka_aborted_txn_start_offsets_t
111
+ *
112
+ * @brief A sorted list of aborted transaction start offsets
113
+ * (ascending) for a PID, and an offset into that list.
114
+ */
115
+ typedef struct rd_kafka_aborted_txn_start_offsets_s {
116
+ rd_avl_node_t avl_node;
117
+ int64_t pid;
118
+ int offsets_idx;
119
+ rd_list_t offsets;
120
+ } rd_kafka_aborted_txn_start_offsets_t;
121
+
122
+
123
+ typedef struct rd_kafka_msgset_reader_s {
124
+ rd_kafka_buf_t *msetr_rkbuf; /**< Response read buffer */
125
+
126
+ int msetr_relative_offsets; /**< Bool: using relative offsets */
127
+
128
+ /**< Outer/wrapper Message fields. */
129
+ struct {
130
+ int64_t offset; /**< Relative_offsets: outer message's
131
+ * Offset (last offset) */
132
+ rd_kafka_timestamp_type_t tstype; /**< Compressed
133
+ * MessageSet's
134
+ * timestamp type. */
135
+ int64_t timestamp; /**< ... timestamp*/
136
+ } msetr_outer;
137
+
138
+ struct msgset_v2_hdr *msetr_v2_hdr; /**< MessageSet v2 header */
139
+
140
+ /*
141
+ * Aborted Transaction Start Offsets. These are arranged in a map
142
+ * (ABORTED_TXN_OFFSETS), with PID as the key and value as follows:
143
+ * - OFFSETS: sorted list of aborted transaction start offsets
144
+ * (ascending)
145
+ * - IDX: an index into OFFSETS list, initialized to 0.
146
+ *
147
+ * The logic for processing fetched data is as follows (note: this is
148
+ * different from the Java client):
149
+ *
150
+ * 1. If the message is a transaction control message and the status is
151
+ * ABORT then increment ABORTED_TXN_OFFSETS(PID).IDX. note: sanity check
152
+ * that OFFSETS[ABORTED_TXN_OFFSETS(PID).IDX] is less than the current
153
+ * offset before incrementing. If the status is COMMIT, do nothing.
154
+ *
155
+ * 2. If the message is a normal message, find the corresponding OFFSETS
156
+ * list in ABORTED_TXN_OFFSETS. If it doesn't exist, then keep the
157
+ * message. If the PID does exist, compare ABORTED_TXN_OFFSETS(PID).IDX
158
+ * with len(OFFSETS). If it's >= then the message should be kept. If
159
+ * not, compare the message offset with
160
+ * OFFSETS[ABORTED_TXN_OFFSETS(PID).IDX]. If it's greater than or equal
161
+ * to this value, then the message should be ignored. If it's less than,
162
+ * then the message should be kept.
163
+ *
164
+ * Note: A MessageSet comprises messages from at most one transaction,
165
+ * so the logic in step 2 is done at the message set level.
166
+ */
167
+ rd_kafka_aborted_txns_t *msetr_aborted_txns;
168
+
169
+ const struct rd_kafka_toppar_ver *msetr_tver; /**< Toppar op version of
170
+ * request. */
171
+
172
+ int32_t msetr_leader_epoch; /**< Current MessageSet's partition
173
+ * leader epoch (or -1). */
174
+
175
+ int32_t msetr_broker_id; /**< Broker id (of msetr_rkb) */
176
+ rd_kafka_broker_t *msetr_rkb; /* @warning Not a refcounted
177
+ * reference! */
178
+ rd_kafka_toppar_t *msetr_rktp; /* @warning Not a refcounted
179
+ * reference! */
180
+
181
+ int msetr_msgcnt; /**< Number of messages in rkq */
182
+ int64_t msetr_msg_bytes; /**< Number of bytes in rkq */
183
+ rd_kafka_q_t msetr_rkq; /**< Temp Message and error queue */
184
+ rd_kafka_q_t *msetr_par_rkq; /**< Parent message and error queue,
185
+ * the temp msetr_rkq will be moved
186
+ * to this queue when parsing
187
+ * is done.
188
+ * Refcount is not increased. */
189
+
190
+ int64_t msetr_next_offset; /**< Next offset to fetch after
191
+ * this reader run is done.
192
+ * Optional: only used for special
193
+ * cases where the per-message offset
194
+ * can't be relied on for next
195
+ * fetch offset, such as with
196
+ * compacted topics. */
197
+
198
+ int msetr_ctrl_cnt; /**< Number of control messages
199
+ * or MessageSets received. */
200
+
201
+ int msetr_aborted_cnt; /**< Number of aborted MessageSets
202
+ * encountered. */
203
+
204
+ const char *msetr_srcname; /**< Optional message source string,
205
+ * used in debug logging to
206
+ * indicate messages were
207
+ * from an inner compressed
208
+ * message set.
209
+ * Not freed (use const memory).
210
+ * Add trailing space. */
211
+
212
+ rd_kafka_compression_t msetr_compression; /**< Compression codec */
213
+ } rd_kafka_msgset_reader_t;
214
+
215
+
216
+
217
+ /* Forward declarations */
218
+ static rd_kafka_resp_err_t
219
+ rd_kafka_msgset_reader_run(rd_kafka_msgset_reader_t *msetr);
220
+ static rd_kafka_resp_err_t
221
+ rd_kafka_msgset_reader_msgs_v2(rd_kafka_msgset_reader_t *msetr);
222
+
223
+
224
+ /**
225
+ * @brief Set up a MessageSet reader but don't start reading messages.
226
+ */
227
+ static void rd_kafka_msgset_reader_init(rd_kafka_msgset_reader_t *msetr,
228
+ rd_kafka_buf_t *rkbuf,
229
+ rd_kafka_toppar_t *rktp,
230
+ const struct rd_kafka_toppar_ver *tver,
231
+ rd_kafka_aborted_txns_t *aborted_txns,
232
+ rd_kafka_q_t *par_rkq) {
233
+
234
+ memset(msetr, 0, sizeof(*msetr));
235
+
236
+ msetr->msetr_rkb = rkbuf->rkbuf_rkb;
237
+ msetr->msetr_leader_epoch = -1;
238
+ msetr->msetr_broker_id = rd_kafka_broker_id(msetr->msetr_rkb);
239
+ msetr->msetr_rktp = rktp;
240
+ msetr->msetr_aborted_txns = aborted_txns;
241
+ msetr->msetr_tver = tver;
242
+ msetr->msetr_rkbuf = rkbuf;
243
+ msetr->msetr_srcname = "";
244
+
245
+ rkbuf->rkbuf_uflow_mitigation = "truncated response from broker (ok)";
246
+
247
+ /* All parsed messages are put on this temporary op
248
+ * queue first and then moved in one go to the real op queue. */
249
+ rd_kafka_q_init(&msetr->msetr_rkq, msetr->msetr_rkb->rkb_rk);
250
+
251
+ /* Make sure enqueued ops get the correct serve/opaque reflecting the
252
+ * original queue. */
253
+ msetr->msetr_rkq.rkq_serve = par_rkq->rkq_serve;
254
+ msetr->msetr_rkq.rkq_opaque = par_rkq->rkq_opaque;
255
+
256
+ /* Keep (non-refcounted) reference to parent queue for
257
+ * moving the messages and events in msetr_rkq to when
258
+ * parsing is done. */
259
+ msetr->msetr_par_rkq = par_rkq;
260
+ }
261
+
262
+
263
+
264
+ /**
265
+ * @brief Decompress MessageSet, pass the uncompressed MessageSet to
266
+ * the MessageSet reader.
267
+ */
268
+ static rd_kafka_resp_err_t
269
+ rd_kafka_msgset_reader_decompress(rd_kafka_msgset_reader_t *msetr,
270
+ int MsgVersion,
271
+ int Attributes,
272
+ int64_t Timestamp,
273
+ int64_t Offset,
274
+ const void *compressed,
275
+ size_t compressed_size) {
276
+ struct iovec iov = {.iov_base = NULL, .iov_len = 0};
277
+ rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
278
+ int codec = Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK;
279
+ rd_kafka_resp_err_t err = RD_KAFKA_RESP_ERR_NO_ERROR;
280
+ rd_kafka_buf_t *rkbufz;
281
+
282
+ msetr->msetr_compression = codec;
283
+
284
+ switch (codec) {
285
+ #if WITH_ZLIB
286
+ case RD_KAFKA_COMPRESSION_GZIP: {
287
+ uint64_t outlenx = 0;
288
+
289
+ /* Decompress Message payload */
290
+ iov.iov_base = rd_gz_decompress(compressed,
291
+ (int)compressed_size, &outlenx);
292
+ if (unlikely(!iov.iov_base)) {
293
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "GZIP",
294
+ "Failed to decompress Gzip "
295
+ "message at offset %" PRId64 " of %" PRIusz
296
+ " bytes: "
297
+ "ignoring message",
298
+ Offset, compressed_size);
299
+ err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
300
+ goto err;
301
+ }
302
+
303
+ iov.iov_len = (size_t)outlenx;
304
+ } break;
305
+ #endif
306
+
307
+ #if WITH_SNAPPY
308
+ case RD_KAFKA_COMPRESSION_SNAPPY: {
309
+ const char *inbuf = compressed;
310
+ size_t inlen = compressed_size;
311
+ int r;
312
+ static const unsigned char snappy_java_magic[] = {
313
+ 0x82, 'S', 'N', 'A', 'P', 'P', 'Y', 0};
314
+ static const size_t snappy_java_hdrlen = 8 + 4 + 4;
315
+
316
+ /* snappy-java adds its own header (SnappyCodec)
317
+ * which is not compatible with the official Snappy
318
+ * implementation.
319
+ * 8: magic, 4: version, 4: compatible
320
+ * followed by any number of chunks:
321
+ * 4: length
322
+ * ...: snappy-compressed data. */
323
+ if (likely(inlen > snappy_java_hdrlen + 4 &&
324
+ !memcmp(inbuf, snappy_java_magic, 8))) {
325
+ /* snappy-java framing */
326
+ char errstr[128];
327
+
328
+ inbuf = inbuf + snappy_java_hdrlen;
329
+ inlen -= snappy_java_hdrlen;
330
+ iov.iov_base = rd_kafka_snappy_java_uncompress(
331
+ inbuf, inlen, &iov.iov_len, errstr, sizeof(errstr));
332
+
333
+ if (unlikely(!iov.iov_base)) {
334
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
335
+ "%s [%" PRId32
336
+ "]: "
337
+ "Snappy decompression for message "
338
+ "at offset %" PRId64
339
+ " failed: %s: "
340
+ "ignoring message",
341
+ rktp->rktp_rkt->rkt_topic->str,
342
+ rktp->rktp_partition, Offset,
343
+ errstr);
344
+ err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
345
+ goto err;
346
+ }
347
+
348
+
349
+ } else {
350
+ /* No framing */
351
+
352
+ /* Acquire uncompressed length */
353
+ if (unlikely(!rd_kafka_snappy_uncompressed_length(
354
+ inbuf, inlen, &iov.iov_len))) {
355
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
356
+ "Failed to get length of Snappy "
357
+ "compressed payload "
358
+ "for message at offset %" PRId64
359
+ " (%" PRIusz
360
+ " bytes): "
361
+ "ignoring message",
362
+ Offset, inlen);
363
+ err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
364
+ goto err;
365
+ }
366
+
367
+ /* Allocate output buffer for uncompressed data */
368
+ iov.iov_base = rd_malloc(iov.iov_len);
369
+ if (unlikely(!iov.iov_base)) {
370
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
371
+ "Failed to allocate Snappy "
372
+ "decompress buffer of size %" PRIusz
373
+ "for message at offset %" PRId64
374
+ " (%" PRIusz
375
+ " bytes): %s: "
376
+ "ignoring message",
377
+ iov.iov_len, Offset, inlen,
378
+ rd_strerror(errno));
379
+ err = RD_KAFKA_RESP_ERR__CRIT_SYS_RESOURCE;
380
+ goto err;
381
+ }
382
+
383
+ /* Uncompress to outbuf */
384
+ if (unlikely((r = rd_kafka_snappy_uncompress(
385
+ inbuf, inlen, iov.iov_base)))) {
386
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "SNAPPY",
387
+ "Failed to decompress Snappy "
388
+ "payload for message at offset "
389
+ "%" PRId64 " (%" PRIusz
390
+ " bytes): %s: "
391
+ "ignoring message",
392
+ Offset, inlen,
393
+ rd_strerror(-r /*negative errno*/));
394
+ rd_free(iov.iov_base);
395
+ err = RD_KAFKA_RESP_ERR__BAD_COMPRESSION;
396
+ goto err;
397
+ }
398
+ }
399
+
400
+ } break;
401
+ #endif
402
+
403
+ case RD_KAFKA_COMPRESSION_LZ4: {
404
+ err =
405
+ rd_kafka_lz4_decompress(msetr->msetr_rkb,
406
+ /* Proper HC? */
407
+ MsgVersion >= 1 ? 1 : 0, Offset,
408
+ /* @warning Will modify compressed
409
+ * if no proper HC */
410
+ (char *)compressed, compressed_size,
411
+ &iov.iov_base, &iov.iov_len);
412
+ if (err)
413
+ goto err;
414
+ } break;
415
+
416
+ #if WITH_ZSTD
417
+ case RD_KAFKA_COMPRESSION_ZSTD: {
418
+ err = rd_kafka_zstd_decompress(
419
+ msetr->msetr_rkb, (char *)compressed, compressed_size,
420
+ &iov.iov_base, &iov.iov_len);
421
+ if (err)
422
+ goto err;
423
+ } break;
424
+ #endif
425
+
426
+ default:
427
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "CODEC",
428
+ "%s [%" PRId32 "]: Message at offset %" PRId64
429
+ " with unsupported "
430
+ "compression codec 0x%x: message ignored",
431
+ rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
432
+ Offset, (int)codec);
433
+
434
+ err = RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED;
435
+ goto err;
436
+ }
437
+
438
+
439
+ rd_assert(iov.iov_base);
440
+
441
+ /*
442
+ * Decompression successful
443
+ */
444
+
445
+ /* Create a new buffer pointing to the uncompressed
446
+ * allocated buffer (outbuf) and let messages keep a reference to
447
+ * this new buffer. */
448
+ rkbufz = rd_kafka_buf_new_shadow(iov.iov_base, iov.iov_len, rd_free);
449
+ rkbufz->rkbuf_rkb = msetr->msetr_rkbuf->rkbuf_rkb;
450
+ rd_kafka_broker_keep(rkbufz->rkbuf_rkb);
451
+
452
+
453
+ /* In MsgVersion v0..1 the decompressed data contains
454
+ * an inner MessageSet, pass it to a new MessageSet reader.
455
+ *
456
+ * For MsgVersion v2 the decompressed data are the list of messages.
457
+ */
458
+
459
+ if (MsgVersion <= 1) {
460
+ /* Pass decompressed data (inner Messageset)
461
+ * to new instance of the MessageSet parser. */
462
+ rd_kafka_msgset_reader_t inner_msetr;
463
+ rd_kafka_msgset_reader_init(
464
+ &inner_msetr, rkbufz, msetr->msetr_rktp, msetr->msetr_tver,
465
+ /* there is no aborted transaction
466
+ * support for MsgVersion < 2 */
467
+ NULL, &msetr->msetr_rkq);
468
+
469
+ inner_msetr.msetr_srcname = "compressed ";
470
+
471
+ if (MsgVersion == 1) {
472
+ /* postproc() will convert relative to
473
+ * absolute offsets */
474
+ inner_msetr.msetr_relative_offsets = 1;
475
+ inner_msetr.msetr_outer.offset = Offset;
476
+
477
+ /* Apply single LogAppendTime timestamp for
478
+ * all messages. */
479
+ if (Attributes & RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME) {
480
+ inner_msetr.msetr_outer.tstype =
481
+ RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME;
482
+ inner_msetr.msetr_outer.timestamp = Timestamp;
483
+ }
484
+ }
485
+
486
+ /* Parse the inner MessageSet */
487
+ err = rd_kafka_msgset_reader_run(&inner_msetr);
488
+
489
+ /* Transfer message count from inner to outer */
490
+ msetr->msetr_msgcnt += inner_msetr.msetr_msgcnt;
491
+ msetr->msetr_msg_bytes += inner_msetr.msetr_msg_bytes;
492
+
493
+
494
+ } else {
495
+ /* MsgVersion 2 */
496
+ rd_kafka_buf_t *orig_rkbuf = msetr->msetr_rkbuf;
497
+
498
+ rkbufz->rkbuf_uflow_mitigation =
499
+ "truncated response from broker (ok)";
500
+
501
+ /* Temporarily replace read buffer with uncompressed buffer */
502
+ msetr->msetr_rkbuf = rkbufz;
503
+
504
+ /* Read messages */
505
+ err = rd_kafka_msgset_reader_msgs_v2(msetr);
506
+
507
+ /* Restore original buffer */
508
+ msetr->msetr_rkbuf = orig_rkbuf;
509
+ }
510
+
511
+ /* Loose our refcnt of the uncompressed rkbuf.
512
+ * Individual messages/rko's will have their own reference. */
513
+ rd_kafka_buf_destroy(rkbufz);
514
+
515
+ return err;
516
+
517
+ err:
518
+ /* Enqueue error messsage:
519
+ * Create op and push on temporary queue. */
520
+ rd_kafka_consumer_err(
521
+ &msetr->msetr_rkq, msetr->msetr_broker_id, err,
522
+ msetr->msetr_tver->version, NULL, rktp, Offset,
523
+ "Decompression (codec 0x%x) of message at %" PRIu64 " of %" PRIusz
524
+ " bytes failed: %s",
525
+ codec, Offset, compressed_size, rd_kafka_err2str(err));
526
+
527
+ return err;
528
+ }
529
+
530
+
531
+
532
+ /**
533
+ * @brief Message parser for MsgVersion v0..1
534
+ *
535
+ * @returns RD_KAFKA_RESP_ERR_NO_ERROR on success or on single-message errors,
536
+ * or any other error code when the MessageSet parser should stop
537
+ * parsing (such as for partial Messages).
538
+ */
539
+ static rd_kafka_resp_err_t
540
+ rd_kafka_msgset_reader_msg_v0_1(rd_kafka_msgset_reader_t *msetr) {
541
+ rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
542
+ rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
543
+ rd_kafka_broker_t *rkb = msetr->msetr_rkb;
544
+ struct {
545
+ int64_t Offset; /* MessageSet header */
546
+ int32_t MessageSize; /* MessageSet header */
547
+ int32_t Crc;
548
+ int8_t MagicByte; /* MsgVersion */
549
+ int8_t Attributes;
550
+ int64_t Timestamp; /* v1 */
551
+ } hdr; /* Message header */
552
+ rd_kafkap_bytes_t Key;
553
+ rd_kafkap_bytes_t Value;
554
+ int32_t Value_len;
555
+ rd_kafka_op_t *rko;
556
+ size_t hdrsize = 6; /* Header size following MessageSize */
557
+ rd_slice_t crc_slice;
558
+ rd_kafka_msg_t *rkm;
559
+ int relative_offsets = 0;
560
+ const char *reloff_str = "";
561
+ /* Only log decoding errors if protocol debugging enabled. */
562
+ int log_decode_errors =
563
+ (rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
564
+ ? LOG_DEBUG
565
+ : 0;
566
+ size_t message_end;
567
+
568
+ rd_kafka_buf_read_i64(rkbuf, &hdr.Offset);
569
+ rd_kafka_buf_read_i32(rkbuf, &hdr.MessageSize);
570
+ message_end = rd_slice_offset(&rkbuf->rkbuf_reader) + hdr.MessageSize;
571
+
572
+ rd_kafka_buf_read_i32(rkbuf, &hdr.Crc);
573
+ if (!rd_slice_narrow_copy_relative(&rkbuf->rkbuf_reader, &crc_slice,
574
+ hdr.MessageSize - 4))
575
+ rd_kafka_buf_check_len(rkbuf, hdr.MessageSize - 4);
576
+
577
+ rd_kafka_buf_read_i8(rkbuf, &hdr.MagicByte);
578
+ rd_kafka_buf_read_i8(rkbuf, &hdr.Attributes);
579
+
580
+ if (hdr.MagicByte == 1) { /* MsgVersion */
581
+ rd_kafka_buf_read_i64(rkbuf, &hdr.Timestamp);
582
+ hdrsize += 8;
583
+ /* MsgVersion 1 has relative offsets for compressed
584
+ * MessageSets*/
585
+ if (!(hdr.Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK) &&
586
+ msetr->msetr_relative_offsets) {
587
+ relative_offsets = 1;
588
+ reloff_str = "relative ";
589
+ }
590
+ } else
591
+ hdr.Timestamp = 0;
592
+
593
+ /* Verify MessageSize */
594
+ if (unlikely(hdr.MessageSize < (ssize_t)hdrsize))
595
+ rd_kafka_buf_parse_fail(
596
+ rkbuf,
597
+ "Message at %soffset %" PRId64 " MessageSize %" PRId32
598
+ " < hdrsize %" PRIusz,
599
+ reloff_str, hdr.Offset, hdr.MessageSize, hdrsize);
600
+
601
+ /* Early check for partial messages */
602
+ rd_kafka_buf_check_len(rkbuf, hdr.MessageSize - hdrsize);
603
+
604
+ if (rkb->rkb_rk->rk_conf.check_crcs) {
605
+ /* Verify CRC32 if desired. */
606
+ uint32_t calc_crc;
607
+
608
+ calc_crc = rd_slice_crc32(&crc_slice);
609
+ rd_dassert(rd_slice_remains(&crc_slice) == 0);
610
+
611
+ if (unlikely(hdr.Crc != (int32_t)calc_crc)) {
612
+ /* Propagate CRC error to application and
613
+ * continue with next message. */
614
+ rd_kafka_consumer_err(
615
+ &msetr->msetr_rkq, msetr->msetr_broker_id,
616
+ RD_KAFKA_RESP_ERR__BAD_MSG,
617
+ msetr->msetr_tver->version, NULL, rktp, hdr.Offset,
618
+ "Message at %soffset %" PRId64 " (%" PRId32
619
+ " bytes) "
620
+ "failed CRC32 check "
621
+ "(original 0x%" PRIx32
622
+ " != "
623
+ "calculated 0x%" PRIx32 ")",
624
+ reloff_str, hdr.Offset, hdr.MessageSize, hdr.Crc,
625
+ calc_crc);
626
+ rd_kafka_buf_skip_to(rkbuf, message_end);
627
+ rd_atomic64_add(&rkb->rkb_c.rx_err, 1);
628
+ /* Continue with next message */
629
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
630
+ }
631
+ }
632
+
633
+
634
+ /* Extract key */
635
+ rd_kafka_buf_read_kbytes(rkbuf, &Key);
636
+
637
+ /* Extract Value */
638
+ rd_kafka_buf_read_kbytes(rkbuf, &Value);
639
+ Value_len = RD_KAFKAP_BYTES_LEN(&Value);
640
+
641
+ /* MessageSets may contain offsets earlier than we
642
+ * requested (compressed MessageSets in particular),
643
+ * drop the earlier messages.
644
+ * Note: the inner offset may only be trusted for
645
+ * absolute offsets. KIP-31 introduced
646
+ * ApiVersion 2 that maintains relative offsets
647
+ * of compressed messages and the base offset
648
+ * in the outer message is the offset of
649
+ * the *LAST* message in the MessageSet.
650
+ * This requires us to assign offsets
651
+ * after all messages have been read from
652
+ * the messageset, and it also means
653
+ * we cant perform this offset check here
654
+ * in that case. */
655
+ if (!relative_offsets &&
656
+ hdr.Offset < rktp->rktp_offsets.fetch_pos.offset)
657
+ return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue with next msg */
658
+
659
+ /* Handle compressed MessageSet */
660
+ if (unlikely(hdr.Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK))
661
+ return rd_kafka_msgset_reader_decompress(
662
+ msetr, hdr.MagicByte, hdr.Attributes, hdr.Timestamp,
663
+ hdr.Offset, Value.data, Value_len);
664
+
665
+
666
+ /* Pure uncompressed message, this is the innermost
667
+ * handler after all compression and cascaded
668
+ * MessageSets have been peeled off. */
669
+
670
+ /* Create op/message container for message. */
671
+ rko = rd_kafka_op_new_fetch_msg(
672
+ &rkm, rktp, msetr->msetr_tver->version, rkbuf,
673
+ RD_KAFKA_FETCH_POS(hdr.Offset, msetr->msetr_leader_epoch),
674
+ (size_t)RD_KAFKAP_BYTES_LEN(&Key),
675
+ RD_KAFKAP_BYTES_IS_NULL(&Key) ? NULL : Key.data,
676
+ (size_t)RD_KAFKAP_BYTES_LEN(&Value),
677
+ RD_KAFKAP_BYTES_IS_NULL(&Value) ? NULL : Value.data);
678
+
679
+ rkm->rkm_broker_id = msetr->msetr_broker_id;
680
+
681
+ /* Assign message timestamp.
682
+ * If message was in a compressed MessageSet and the outer/wrapper
683
+ * Message.Attribute had a LOG_APPEND_TIME set, use the
684
+ * outer timestamp */
685
+ if (msetr->msetr_outer.tstype == RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME) {
686
+ rkm->rkm_timestamp = msetr->msetr_outer.timestamp;
687
+ rkm->rkm_tstype = msetr->msetr_outer.tstype;
688
+
689
+ } else if (hdr.MagicByte >= 1 && hdr.Timestamp) {
690
+ rkm->rkm_timestamp = hdr.Timestamp;
691
+ if (hdr.Attributes & RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME)
692
+ rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME;
693
+ else
694
+ rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_CREATE_TIME;
695
+ }
696
+
697
+ /* Enqueue message on temporary queue */
698
+ rd_kafka_q_enq(&msetr->msetr_rkq, rko);
699
+ msetr->msetr_msgcnt++;
700
+ msetr->msetr_msg_bytes += rkm->rkm_key_len + rkm->rkm_len;
701
+
702
+ return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue */
703
+
704
+ err_parse:
705
+ /* Count all parse errors as partial message errors. */
706
+ rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
707
+ return rkbuf->rkbuf_err;
708
+ }
709
+
710
+
711
+
712
+ /**
713
+ * @brief Message parser for MsgVersion v2
714
+ */
715
+ static rd_kafka_resp_err_t
716
+ rd_kafka_msgset_reader_msg_v2(rd_kafka_msgset_reader_t *msetr) {
717
+ rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
718
+ rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
719
+ struct {
720
+ int64_t Length;
721
+ int8_t MsgAttributes;
722
+ int64_t TimestampDelta;
723
+ int64_t OffsetDelta;
724
+ int64_t Offset; /* Absolute offset */
725
+ rd_kafkap_bytes_t Key;
726
+ rd_kafkap_bytes_t Value;
727
+ rd_kafkap_bytes_t Headers;
728
+ } hdr;
729
+ rd_kafka_op_t *rko;
730
+ rd_kafka_msg_t *rkm;
731
+ /* Only log decoding errors if protocol debugging enabled. */
732
+ int log_decode_errors =
733
+ (rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
734
+ ? LOG_DEBUG
735
+ : 0;
736
+ size_t message_end;
737
+ rd_kafka_fetch_pos_t msetr_pos;
738
+
739
+ rd_kafka_buf_read_varint(rkbuf, &hdr.Length);
740
+ message_end =
741
+ rd_slice_offset(&rkbuf->rkbuf_reader) + (size_t)hdr.Length;
742
+ rd_kafka_buf_read_i8(rkbuf, &hdr.MsgAttributes);
743
+
744
+ rd_kafka_buf_read_varint(rkbuf, &hdr.TimestampDelta);
745
+ rd_kafka_buf_read_varint(rkbuf, &hdr.OffsetDelta);
746
+ hdr.Offset = msetr->msetr_v2_hdr->BaseOffset + hdr.OffsetDelta;
747
+ msetr_pos = RD_KAFKA_FETCH_POS(hdr.Offset, msetr->msetr_leader_epoch);
748
+
749
+ /* Skip message if outdated.
750
+ * Don't check offset leader epoch, just log it, as if current leader
751
+ * epoch is different the fetch will fail (KIP-320) and if offset leader
752
+ * epoch is different it'll return an empty fetch (KIP-595). If we
753
+ * checked it, it's possible to have a loop when moving from a broker
754
+ * that supports leader epoch to one that doesn't. */
755
+ if (hdr.Offset < rktp->rktp_offsets.fetch_pos.offset) {
756
+ rd_rkb_dbg(
757
+ msetr->msetr_rkb, MSG, "MSG",
758
+ "%s [%" PRId32
759
+ "]: "
760
+ "Skip %s < fetch %s",
761
+ rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
762
+ rd_kafka_fetch_pos2str(msetr_pos),
763
+ rd_kafka_fetch_pos2str(rktp->rktp_offsets.fetch_pos));
764
+ rd_kafka_buf_skip_to(rkbuf, message_end);
765
+ return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue with next msg */
766
+ }
767
+
768
+ /* Handle control messages */
769
+ if (msetr->msetr_v2_hdr->Attributes & RD_KAFKA_MSGSET_V2_ATTR_CONTROL) {
770
+ struct {
771
+ int64_t KeySize;
772
+ int16_t Version;
773
+ int16_t Type;
774
+ } ctrl_data;
775
+ int64_t aborted_txn_start_offset;
776
+
777
+ rd_kafka_buf_read_varint(rkbuf, &ctrl_data.KeySize);
778
+
779
+ if (unlikely(ctrl_data.KeySize < 2))
780
+ rd_kafka_buf_parse_fail(
781
+ rkbuf,
782
+ "%s [%" PRId32
783
+ "]: "
784
+ "Ctrl message at %s"
785
+ " has invalid key size %" PRId64,
786
+ rktp->rktp_rkt->rkt_topic->str,
787
+ rktp->rktp_partition,
788
+ rd_kafka_fetch_pos2str(msetr_pos),
789
+ ctrl_data.KeySize);
790
+
791
+ rd_kafka_buf_read_i16(rkbuf, &ctrl_data.Version);
792
+
793
+ if (ctrl_data.Version != 0) {
794
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "MSG",
795
+ "%s [%" PRId32
796
+ "]: "
797
+ "Skipping ctrl msg with "
798
+ "unsupported version %" PRId16 " at %s",
799
+ rktp->rktp_rkt->rkt_topic->str,
800
+ rktp->rktp_partition, ctrl_data.Version,
801
+ rd_kafka_fetch_pos2str(msetr_pos));
802
+ rd_kafka_buf_skip_to(rkbuf, message_end);
803
+ return RD_KAFKA_RESP_ERR_NO_ERROR; /* Continue with next
804
+ msg */
805
+ }
806
+
807
+ if (unlikely(ctrl_data.KeySize != 4))
808
+ rd_kafka_buf_parse_fail(
809
+ rkbuf,
810
+ "%s [%" PRId32
811
+ "]: "
812
+ "Ctrl message at %s"
813
+ " has invalid key size %" PRId64,
814
+ rktp->rktp_rkt->rkt_topic->str,
815
+ rktp->rktp_partition,
816
+ rd_kafka_fetch_pos2str(msetr_pos),
817
+ ctrl_data.KeySize);
818
+
819
+ rd_kafka_buf_read_i16(rkbuf, &ctrl_data.Type);
820
+
821
+ /* Client is uninterested in value of commit marker */
822
+ rd_kafka_buf_skip(
823
+ rkbuf, (int32_t)(message_end -
824
+ rd_slice_offset(&rkbuf->rkbuf_reader)));
825
+
826
+ switch (ctrl_data.Type) {
827
+ case RD_KAFKA_CTRL_MSG_COMMIT:
828
+ /* always ignore. */
829
+ break;
830
+
831
+ case RD_KAFKA_CTRL_MSG_ABORT:
832
+ if (msetr->msetr_rkb->rkb_rk->rk_conf.isolation_level !=
833
+ RD_KAFKA_READ_COMMITTED)
834
+ break;
835
+
836
+ if (unlikely(!msetr->msetr_aborted_txns)) {
837
+ rd_rkb_dbg(msetr->msetr_rkb,
838
+ MSG | RD_KAFKA_DBG_EOS, "TXN",
839
+ "%s [%" PRId32
840
+ "] received abort txn "
841
+ "ctrl msg at %s"
842
+ " for "
843
+ "PID %" PRId64
844
+ ", but there are no "
845
+ "known aborted transactions: "
846
+ "ignoring",
847
+ rktp->rktp_rkt->rkt_topic->str,
848
+ rktp->rktp_partition,
849
+ rd_kafka_fetch_pos2str(msetr_pos),
850
+ msetr->msetr_v2_hdr->PID);
851
+ break;
852
+ }
853
+
854
+ /* This marks the end of this (aborted) transaction,
855
+ * advance to next aborted transaction in list */
856
+ aborted_txn_start_offset =
857
+ rd_kafka_aborted_txns_pop_offset(
858
+ msetr->msetr_aborted_txns,
859
+ msetr->msetr_v2_hdr->PID, msetr_pos.offset);
860
+
861
+ if (unlikely(aborted_txn_start_offset == -1)) {
862
+ rd_rkb_dbg(msetr->msetr_rkb,
863
+ MSG | RD_KAFKA_DBG_EOS, "TXN",
864
+ "%s [%" PRId32
865
+ "] received abort txn "
866
+ "ctrl msg at %s"
867
+ " for "
868
+ "PID %" PRId64
869
+ ", but this offset is "
870
+ "not listed as an aborted "
871
+ "transaction: aborted transaction "
872
+ "was possibly empty: ignoring",
873
+ rktp->rktp_rkt->rkt_topic->str,
874
+ rktp->rktp_partition,
875
+ rd_kafka_fetch_pos2str(msetr_pos),
876
+ msetr->msetr_v2_hdr->PID);
877
+ break;
878
+ }
879
+ break;
880
+
881
+
882
+ default:
883
+ rd_rkb_dbg(msetr->msetr_rkb, MSG,
884
+ "TXN"
885
+ "%s [%" PRId32
886
+ "]: "
887
+ "Unsupported ctrl message "
888
+ "type %" PRId16
889
+ " at "
890
+ " %s: ignoring",
891
+ rktp->rktp_rkt->rkt_topic->str,
892
+ rktp->rktp_partition, ctrl_data.Type,
893
+ rd_kafka_fetch_pos2str(msetr_pos));
894
+ break;
895
+ }
896
+
897
+ rko = rd_kafka_op_new_ctrl_msg(rktp, msetr->msetr_tver->version,
898
+ rkbuf, msetr_pos);
899
+ rd_kafka_q_enq(&msetr->msetr_rkq, rko);
900
+ msetr->msetr_msgcnt++;
901
+
902
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
903
+ }
904
+
905
+ /* Regular message */
906
+
907
+ /* Note: messages in aborted transactions are skipped at the MessageSet
908
+ * level */
909
+
910
+ rd_kafka_buf_read_kbytes_varint(rkbuf, &hdr.Key);
911
+ rd_kafka_buf_read_kbytes_varint(rkbuf, &hdr.Value);
912
+
913
+ /* We parse the Headers later, just store the size (possibly truncated)
914
+ * and pointer to the headers. */
915
+ hdr.Headers.len =
916
+ (int32_t)(message_end - rd_slice_offset(&rkbuf->rkbuf_reader));
917
+ rd_kafka_buf_read_ptr(rkbuf, &hdr.Headers.data, hdr.Headers.len);
918
+
919
+ /* Create op/message container for message. */
920
+ rko = rd_kafka_op_new_fetch_msg(
921
+ &rkm, rktp, msetr->msetr_tver->version, rkbuf, msetr_pos,
922
+ (size_t)RD_KAFKAP_BYTES_LEN(&hdr.Key),
923
+ RD_KAFKAP_BYTES_IS_NULL(&hdr.Key) ? NULL : hdr.Key.data,
924
+ (size_t)RD_KAFKAP_BYTES_LEN(&hdr.Value),
925
+ RD_KAFKAP_BYTES_IS_NULL(&hdr.Value) ? NULL : hdr.Value.data);
926
+
927
+ rkm->rkm_broker_id = msetr->msetr_broker_id;
928
+
929
+ /* Store pointer to unparsed message headers, they will
930
+ * be parsed on the first access.
931
+ * This pointer points to the rkbuf payload.
932
+ * Note: can't perform struct copy here due to const fields (MSVC) */
933
+ rkm->rkm_u.consumer.binhdrs.len = hdr.Headers.len;
934
+ rkm->rkm_u.consumer.binhdrs.data = hdr.Headers.data;
935
+
936
+ /* Set timestamp.
937
+ *
938
+ * When broker assigns the timestamps (LOG_APPEND_TIME) it will
939
+ * assign the same timestamp for all messages in a MessageSet
940
+ * using MaxTimestamp.
941
+ */
942
+ if ((msetr->msetr_v2_hdr->Attributes &
943
+ RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME) ||
944
+ (hdr.MsgAttributes & RD_KAFKA_MSG_ATTR_LOG_APPEND_TIME)) {
945
+ rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_LOG_APPEND_TIME;
946
+ rkm->rkm_timestamp = msetr->msetr_v2_hdr->MaxTimestamp;
947
+ } else {
948
+ rkm->rkm_tstype = RD_KAFKA_TIMESTAMP_CREATE_TIME;
949
+ rkm->rkm_timestamp =
950
+ msetr->msetr_v2_hdr->BaseTimestamp + hdr.TimestampDelta;
951
+ }
952
+
953
+
954
+ /* Enqueue message on temporary queue */
955
+ rd_kafka_q_enq(&msetr->msetr_rkq, rko);
956
+ msetr->msetr_msgcnt++;
957
+ msetr->msetr_msg_bytes += rkm->rkm_key_len + rkm->rkm_len;
958
+
959
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
960
+
961
+ err_parse:
962
+ /* Count all parse errors as partial message errors. */
963
+ rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
964
+ return rkbuf->rkbuf_err;
965
+ }
966
+
967
+
968
+ /**
969
+ * @brief Read v2 messages from current buffer position.
970
+ */
971
+ static rd_kafka_resp_err_t
972
+ rd_kafka_msgset_reader_msgs_v2(rd_kafka_msgset_reader_t *msetr) {
973
+ rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
974
+ rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
975
+ /* Only log decoding errors if protocol debugging enabled. */
976
+ int log_decode_errors =
977
+ (rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
978
+ ? LOG_DEBUG
979
+ : 0;
980
+
981
+ if (msetr->msetr_aborted_txns != NULL &&
982
+ (msetr->msetr_v2_hdr->Attributes &
983
+ (RD_KAFKA_MSGSET_V2_ATTR_TRANSACTIONAL |
984
+ RD_KAFKA_MSGSET_V2_ATTR_CONTROL)) ==
985
+ RD_KAFKA_MSGSET_V2_ATTR_TRANSACTIONAL) {
986
+ /* Transactional non-control MessageSet:
987
+ * check if it is part of an aborted transaction. */
988
+ int64_t txn_start_offset = rd_kafka_aborted_txns_get_offset(
989
+ msetr->msetr_aborted_txns, msetr->msetr_v2_hdr->PID);
990
+
991
+ if (txn_start_offset != -1 &&
992
+ msetr->msetr_v2_hdr->BaseOffset >= txn_start_offset) {
993
+ /* MessageSet is part of aborted transaction */
994
+ rd_rkb_dbg(msetr->msetr_rkb, MSG, "MSG",
995
+ "%s [%" PRId32
996
+ "]: "
997
+ "Skipping %" PRId32
998
+ " message(s) "
999
+ "in aborted transaction "
1000
+ "at offset %" PRId64 " for PID %" PRId64,
1001
+ rktp->rktp_rkt->rkt_topic->str,
1002
+ rktp->rktp_partition,
1003
+ msetr->msetr_v2_hdr->RecordCount,
1004
+ txn_start_offset, msetr->msetr_v2_hdr->PID);
1005
+ rd_kafka_buf_skip(
1006
+ msetr->msetr_rkbuf,
1007
+ rd_slice_remains(
1008
+ &msetr->msetr_rkbuf->rkbuf_reader));
1009
+ msetr->msetr_aborted_cnt++;
1010
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
1011
+ }
1012
+ }
1013
+
1014
+ while (rd_kafka_buf_read_remain(msetr->msetr_rkbuf)) {
1015
+ rd_kafka_resp_err_t err;
1016
+ err = rd_kafka_msgset_reader_msg_v2(msetr);
1017
+ if (unlikely(err))
1018
+ return err;
1019
+ }
1020
+
1021
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
1022
+
1023
+ err_parse:
1024
+ /* Count all parse errors as partial message errors. */
1025
+ rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
1026
+ msetr->msetr_v2_hdr = NULL;
1027
+ return rkbuf->rkbuf_err;
1028
+ }
1029
+
1030
+
1031
+
1032
+ /**
1033
+ * @brief MessageSet reader for MsgVersion v2 (FetchRequest v4)
1034
+ */
1035
+ static rd_kafka_resp_err_t
1036
+ rd_kafka_msgset_reader_v2(rd_kafka_msgset_reader_t *msetr) {
1037
+ rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
1038
+ rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
1039
+ struct msgset_v2_hdr hdr;
1040
+ rd_slice_t save_slice;
1041
+ rd_kafka_resp_err_t err = RD_KAFKA_RESP_ERR_NO_ERROR;
1042
+ size_t len_start;
1043
+ size_t payload_size;
1044
+ int64_t LastOffset; /* Last absolute Offset in MessageSet header */
1045
+ /* Only log decoding errors if protocol debugging enabled. */
1046
+ int log_decode_errors =
1047
+ (rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
1048
+ ? LOG_DEBUG
1049
+ : 0;
1050
+
1051
+ rd_kafka_buf_read_i64(rkbuf, &hdr.BaseOffset);
1052
+ rd_kafka_buf_read_i32(rkbuf, &hdr.Length);
1053
+ len_start = rd_slice_offset(&rkbuf->rkbuf_reader);
1054
+
1055
+ if (unlikely(hdr.Length < RD_KAFKAP_MSGSET_V2_SIZE - 8 - 4))
1056
+ rd_kafka_buf_parse_fail(rkbuf,
1057
+ "%s [%" PRId32
1058
+ "] "
1059
+ "MessageSet at offset %" PRId64
1060
+ " length %" PRId32 " < header size %d",
1061
+ rktp->rktp_rkt->rkt_topic->str,
1062
+ rktp->rktp_partition, hdr.BaseOffset,
1063
+ hdr.Length,
1064
+ RD_KAFKAP_MSGSET_V2_SIZE - 8 - 4);
1065
+
1066
+ rd_kafka_buf_read_i32(rkbuf, &hdr.PartitionLeaderEpoch);
1067
+ msetr->msetr_leader_epoch = hdr.PartitionLeaderEpoch;
1068
+
1069
+ rd_kafka_buf_read_i8(rkbuf, &hdr.MagicByte);
1070
+ rd_kafka_buf_read_i32(rkbuf, &hdr.Crc);
1071
+
1072
+ if (msetr->msetr_rkb->rkb_rk->rk_conf.check_crcs) {
1073
+ /* Verify CRC32C if desired. */
1074
+ uint32_t calc_crc;
1075
+ rd_slice_t crc_slice;
1076
+ size_t crc_len = hdr.Length - 4 - 1 - 4;
1077
+
1078
+ if (!rd_slice_narrow_copy_relative(&rkbuf->rkbuf_reader,
1079
+ &crc_slice, crc_len))
1080
+ rd_kafka_buf_check_len(rkbuf, crc_len);
1081
+
1082
+ calc_crc = rd_slice_crc32c(&crc_slice);
1083
+
1084
+ if (unlikely((uint32_t)hdr.Crc != calc_crc)) {
1085
+ /* Propagate CRC error to application and
1086
+ * continue with next message. */
1087
+ rd_kafka_consumer_err(
1088
+ &msetr->msetr_rkq, msetr->msetr_broker_id,
1089
+ RD_KAFKA_RESP_ERR__BAD_MSG,
1090
+ msetr->msetr_tver->version, NULL, rktp,
1091
+ hdr.BaseOffset,
1092
+ "MessageSet at offset %" PRId64 " (%" PRId32
1093
+ " bytes) "
1094
+ "failed CRC32C check "
1095
+ "(original 0x%" PRIx32
1096
+ " != "
1097
+ "calculated 0x%" PRIx32 ")",
1098
+ hdr.BaseOffset, hdr.Length, hdr.Crc, calc_crc);
1099
+ rd_kafka_buf_skip_to(rkbuf, crc_len);
1100
+ rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_err, 1);
1101
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
1102
+ }
1103
+ }
1104
+
1105
+ rd_kafka_buf_read_i16(rkbuf, &hdr.Attributes);
1106
+ rd_kafka_buf_read_i32(rkbuf, &hdr.LastOffsetDelta);
1107
+ LastOffset = hdr.BaseOffset + hdr.LastOffsetDelta;
1108
+ rd_kafka_buf_read_i64(rkbuf, &hdr.BaseTimestamp);
1109
+ rd_kafka_buf_read_i64(rkbuf, &hdr.MaxTimestamp);
1110
+ rd_kafka_buf_read_i64(rkbuf, &hdr.PID);
1111
+ rd_kafka_buf_read_i16(rkbuf, &hdr.ProducerEpoch);
1112
+ rd_kafka_buf_read_i32(rkbuf, &hdr.BaseSequence);
1113
+ rd_kafka_buf_read_i32(rkbuf, &hdr.RecordCount);
1114
+
1115
+ /* Payload size is hdr.Length - MessageSet headers */
1116
+ payload_size =
1117
+ hdr.Length - (rd_slice_offset(&rkbuf->rkbuf_reader) - len_start);
1118
+
1119
+ if (unlikely(payload_size > rd_kafka_buf_read_remain(rkbuf)))
1120
+ rd_kafka_buf_underflow_fail(
1121
+ rkbuf, payload_size,
1122
+ "%s [%" PRId32
1123
+ "] "
1124
+ "MessageSet at offset %" PRId64 " payload size %" PRIusz,
1125
+ rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
1126
+ hdr.BaseOffset, payload_size);
1127
+
1128
+ /* If entire MessageSet contains old outdated offsets, skip it. */
1129
+ if (LastOffset < rktp->rktp_offsets.fetch_pos.offset) {
1130
+ rd_kafka_buf_skip(rkbuf, payload_size);
1131
+ goto done;
1132
+ }
1133
+
1134
+ if (hdr.Attributes & RD_KAFKA_MSGSET_V2_ATTR_CONTROL)
1135
+ msetr->msetr_ctrl_cnt++;
1136
+
1137
+ msetr->msetr_v2_hdr = &hdr;
1138
+
1139
+ /* Handle compressed MessageSet */
1140
+ if (hdr.Attributes & RD_KAFKA_MSG_ATTR_COMPRESSION_MASK) {
1141
+ const void *compressed;
1142
+
1143
+ compressed =
1144
+ rd_slice_ensure_contig(&rkbuf->rkbuf_reader, payload_size);
1145
+ rd_assert(compressed);
1146
+
1147
+ err = rd_kafka_msgset_reader_decompress(
1148
+ msetr, 2 /*MsgVersion v2*/, hdr.Attributes,
1149
+ hdr.BaseTimestamp, hdr.BaseOffset, compressed,
1150
+ payload_size);
1151
+ if (err)
1152
+ goto err;
1153
+
1154
+ } else {
1155
+ /* Read uncompressed messages */
1156
+
1157
+ /* Save original slice, reduce size of the current one to
1158
+ * be limited by the MessageSet.Length, and then start reading
1159
+ * messages until the lesser slice is exhausted. */
1160
+ if (!rd_slice_narrow_relative(&rkbuf->rkbuf_reader, &save_slice,
1161
+ payload_size))
1162
+ rd_kafka_buf_check_len(rkbuf, payload_size);
1163
+
1164
+ /* Read messages */
1165
+ err = rd_kafka_msgset_reader_msgs_v2(msetr);
1166
+
1167
+ /* Restore wider slice */
1168
+ rd_slice_widen(&rkbuf->rkbuf_reader, &save_slice);
1169
+
1170
+ if (unlikely(err))
1171
+ goto err;
1172
+ }
1173
+
1174
+
1175
+ done:
1176
+ /* Set the next fetch offset to the MessageSet header's last offset + 1
1177
+ * to avoid getting stuck on compacted MessageSets where the last
1178
+ * Message in the MessageSet has an Offset < MessageSet header's
1179
+ * last offset. See KAFKA-5443 */
1180
+ msetr->msetr_next_offset = LastOffset + 1;
1181
+
1182
+ msetr->msetr_v2_hdr = NULL;
1183
+
1184
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
1185
+
1186
+ err_parse:
1187
+ /* Count all parse errors as partial message errors. */
1188
+ rd_atomic64_add(&msetr->msetr_rkb->rkb_c.rx_partial, 1);
1189
+ err = rkbuf->rkbuf_err;
1190
+ /* FALLTHRU */
1191
+ err:
1192
+ msetr->msetr_v2_hdr = NULL;
1193
+ return err;
1194
+ }
1195
+
1196
+
1197
+ /**
1198
+ * @brief Peek into the next MessageSet to find the MsgVersion.
1199
+ *
1200
+ * @param MagicBytep the MsgVersion is returned here on success.
1201
+ *
1202
+ * @returns an error on read underflow or if the MsgVersion is
1203
+ * unsupported.
1204
+ */
1205
+ static rd_kafka_resp_err_t
1206
+ rd_kafka_msgset_reader_peek_msg_version(rd_kafka_msgset_reader_t *msetr,
1207
+ int8_t *MagicBytep) {
1208
+ rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
1209
+ rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
1210
+ /* Only log decoding errors if protocol debugging enabled. */
1211
+ int log_decode_errors =
1212
+ (rkbuf->rkbuf_rkb->rkb_rk->rk_conf.debug & RD_KAFKA_DBG_PROTOCOL)
1213
+ ? LOG_DEBUG
1214
+ : 0;
1215
+ size_t read_offset = rd_slice_offset(&rkbuf->rkbuf_reader);
1216
+
1217
+ rd_kafka_buf_peek_i8(rkbuf, read_offset + 8 + 4 + 4, MagicBytep);
1218
+
1219
+ if (unlikely(*MagicBytep < 0 || *MagicBytep > 2)) {
1220
+ int64_t Offset; /* For error logging */
1221
+ int32_t Length;
1222
+
1223
+ rd_kafka_buf_read_i64(rkbuf, &Offset);
1224
+
1225
+ rd_rkb_dbg(msetr->msetr_rkb,
1226
+ MSG | RD_KAFKA_DBG_PROTOCOL | RD_KAFKA_DBG_FETCH,
1227
+ "MAGICBYTE",
1228
+ "%s [%" PRId32
1229
+ "]: "
1230
+ "Unsupported Message(Set) MagicByte %d at "
1231
+ "offset %" PRId64
1232
+ " "
1233
+ "(buffer position %" PRIusz "/%" PRIusz
1234
+ "): skipping",
1235
+ rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
1236
+ (int)*MagicBytep, Offset, read_offset,
1237
+ rd_slice_size(&rkbuf->rkbuf_reader));
1238
+
1239
+ if (Offset >=
1240
+ msetr->msetr_rktp->rktp_offsets.fetch_pos.offset) {
1241
+ rd_kafka_consumer_err(
1242
+ &msetr->msetr_rkq, msetr->msetr_broker_id,
1243
+ RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED,
1244
+ msetr->msetr_tver->version, NULL, rktp, Offset,
1245
+ "Unsupported Message(Set) MagicByte %d "
1246
+ "at offset %" PRId64,
1247
+ (int)*MagicBytep, Offset);
1248
+ /* Skip message(set) */
1249
+ msetr->msetr_rktp->rktp_offsets.fetch_pos.offset =
1250
+ Offset + 1;
1251
+ }
1252
+
1253
+ /* Skip this Message(Set).
1254
+ * If the message is malformed, the skip may trigger err_parse
1255
+ * and return ERR__BAD_MSG. */
1256
+ rd_kafka_buf_read_i32(rkbuf, &Length);
1257
+ rd_kafka_buf_skip(rkbuf, Length);
1258
+
1259
+ return RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED;
1260
+ }
1261
+
1262
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
1263
+
1264
+ err_parse:
1265
+ return RD_KAFKA_RESP_ERR__BAD_MSG;
1266
+ }
1267
+
1268
+
1269
+ /**
1270
+ * @brief Parse and read messages from msgset reader buffer.
1271
+ */
1272
+ static rd_kafka_resp_err_t
1273
+ rd_kafka_msgset_reader(rd_kafka_msgset_reader_t *msetr) {
1274
+ rd_kafka_buf_t *rkbuf = msetr->msetr_rkbuf;
1275
+ rd_kafka_resp_err_t (*reader[])(rd_kafka_msgset_reader_t *) = {
1276
+ /* Indexed by MsgVersion/MagicByte, pointing to
1277
+ * a Msg(Set)Version reader */
1278
+ [0] = rd_kafka_msgset_reader_msg_v0_1,
1279
+ [1] = rd_kafka_msgset_reader_msg_v0_1,
1280
+ [2] = rd_kafka_msgset_reader_v2};
1281
+ rd_kafka_resp_err_t err;
1282
+
1283
+ /* Parse MessageSets until the slice is exhausted or an
1284
+ * error occurs (typically a partial message). */
1285
+ do {
1286
+ int8_t MagicByte;
1287
+
1288
+ /* We dont know the MsgVersion at this point, peek where the
1289
+ * MagicByte resides both in MsgVersion v0..1 and v2 to
1290
+ * know which MessageSet reader to use. */
1291
+ err =
1292
+ rd_kafka_msgset_reader_peek_msg_version(msetr, &MagicByte);
1293
+ if (unlikely(err)) {
1294
+ if (err == RD_KAFKA_RESP_ERR__BAD_MSG)
1295
+ /* Read underflow, not an error.
1296
+ * Broker may return a partial Fetch response
1297
+ * due to its use of sendfile(2). */
1298
+ return RD_KAFKA_RESP_ERR_NO_ERROR;
1299
+
1300
+ /* Continue on unsupported MsgVersions, the
1301
+ * MessageSet will be skipped. */
1302
+ continue;
1303
+ }
1304
+
1305
+ /* Use MsgVersion-specific reader */
1306
+ err = reader[(int)MagicByte](msetr);
1307
+
1308
+ } while (!err && rd_slice_remains(&rkbuf->rkbuf_reader) > 0);
1309
+
1310
+ return err;
1311
+ }
1312
+
1313
+
1314
+
1315
+ /**
1316
+ * @brief MessageSet post-processing.
1317
+ *
1318
+ * @param last_offsetp will be set to the offset of the last message in the set,
1319
+ * or -1 if not applicable.
1320
+ */
1321
+ static void rd_kafka_msgset_reader_postproc(rd_kafka_msgset_reader_t *msetr,
1322
+ int64_t *last_offsetp) {
1323
+ rd_kafka_op_t *rko;
1324
+
1325
+ rko = rd_kafka_q_last(&msetr->msetr_rkq, RD_KAFKA_OP_FETCH,
1326
+ 0 /* no error ops */);
1327
+ if (rko) {
1328
+ *last_offsetp = rko->rko_u.fetch.rkm.rkm_offset;
1329
+
1330
+ if (*last_offsetp != -1 && msetr->msetr_relative_offsets) {
1331
+ /* Update messages to absolute offsets
1332
+ * and purge any messages older than the current
1333
+ * fetch offset. */
1334
+ rd_kafka_q_fix_offsets(
1335
+ &msetr->msetr_rkq,
1336
+ msetr->msetr_rktp->rktp_offsets.fetch_pos.offset,
1337
+ msetr->msetr_outer.offset - *last_offsetp);
1338
+ }
1339
+ }
1340
+ }
1341
+
1342
+
1343
+
1344
+ /**
1345
+ * @brief Run the MessageSet reader, read messages until buffer is
1346
+ * exhausted (or error encountered), enqueue parsed messages on
1347
+ * partition queue.
1348
+ *
1349
+ * @returns RD_KAFKA_RESP_ERR_NO_ERROR if MessageSet was successfully
1350
+ * or partially parsed. When other error codes are returned it
1351
+ * indicates a semi-permanent error (such as unsupported MsgVersion)
1352
+ * and the fetcher should back off this partition to avoid
1353
+ * busy-looping.
1354
+ */
1355
+ static rd_kafka_resp_err_t
1356
+ rd_kafka_msgset_reader_run(rd_kafka_msgset_reader_t *msetr) {
1357
+ rd_kafka_toppar_t *rktp = msetr->msetr_rktp;
1358
+ rd_kafka_resp_err_t err;
1359
+ int64_t last_offset = -1;
1360
+
1361
+ /* Parse MessageSets and messages */
1362
+ err = rd_kafka_msgset_reader(msetr);
1363
+
1364
+ if (unlikely(rd_kafka_q_len(&msetr->msetr_rkq) == 0)) {
1365
+ /* The message set didn't contain at least one full message
1366
+ * or no error was posted on the response queue.
1367
+ * This means the size limit perhaps was too tight,
1368
+ * increase it automatically.
1369
+ * If there was at least one control message there
1370
+ * is probably not a size limit and nothing is done.
1371
+ * If there were aborted messagesets and no underflow then
1372
+ * there is no error either (#2993).
1373
+ *
1374
+ * Also; avoid propagating underflow errors, which cause
1375
+ * backoffs, since we'll want to continue fetching the
1376
+ * remaining truncated messages as soon as possible.
1377
+ */
1378
+ if (msetr->msetr_ctrl_cnt > 0) {
1379
+ /* Noop */
1380
+ if (err == RD_KAFKA_RESP_ERR__UNDERFLOW)
1381
+ err = RD_KAFKA_RESP_ERR_NO_ERROR;
1382
+
1383
+ } else if (rktp->rktp_fetch_msg_max_bytes < (1 << 30)) {
1384
+ rktp->rktp_fetch_msg_max_bytes *= 2;
1385
+ rd_rkb_dbg(msetr->msetr_rkb, FETCH, "CONSUME",
1386
+ "Topic %s [%" PRId32
1387
+ "]: Increasing "
1388
+ "max fetch bytes to %" PRId32,
1389
+ rktp->rktp_rkt->rkt_topic->str,
1390
+ rktp->rktp_partition,
1391
+ rktp->rktp_fetch_msg_max_bytes);
1392
+
1393
+ if (err == RD_KAFKA_RESP_ERR__UNDERFLOW)
1394
+ err = RD_KAFKA_RESP_ERR_NO_ERROR;
1395
+
1396
+ } else if (!err && msetr->msetr_aborted_cnt == 0) {
1397
+ rd_kafka_consumer_err(
1398
+ &msetr->msetr_rkq, msetr->msetr_broker_id,
1399
+ RD_KAFKA_RESP_ERR_MSG_SIZE_TOO_LARGE,
1400
+ msetr->msetr_tver->version, NULL, rktp,
1401
+ rktp->rktp_offsets.fetch_pos.offset,
1402
+ "Message at offset %" PRId64
1403
+ " might be too large to fetch, try increasing "
1404
+ "receive.message.max.bytes",
1405
+ rktp->rktp_offsets.fetch_pos.offset);
1406
+
1407
+ } else if (msetr->msetr_aborted_cnt > 0) {
1408
+ /* Noop */
1409
+ if (err == RD_KAFKA_RESP_ERR__UNDERFLOW)
1410
+ err = RD_KAFKA_RESP_ERR_NO_ERROR;
1411
+ }
1412
+
1413
+ } else {
1414
+ /* MessageSet post-processing. */
1415
+ rd_kafka_msgset_reader_postproc(msetr, &last_offset);
1416
+
1417
+ /* Ignore parse errors if there was at least one
1418
+ * good message since it probably indicates a
1419
+ * partial response rather than an erroneous one. */
1420
+ if (err == RD_KAFKA_RESP_ERR__UNDERFLOW &&
1421
+ msetr->msetr_msgcnt > 0)
1422
+ err = RD_KAFKA_RESP_ERR_NO_ERROR;
1423
+ }
1424
+
1425
+ rd_rkb_dbg(msetr->msetr_rkb, MSG | RD_KAFKA_DBG_FETCH, "CONSUME",
1426
+ "Enqueue %i %smessage(s) (%" PRId64
1427
+ " bytes, %d ops) on %s [%" PRId32
1428
+ "] fetch queue (qlen %d, v%d, last_offset %" PRId64
1429
+ ", %d ctrl msgs, %d aborted msgsets, %s)",
1430
+ msetr->msetr_msgcnt, msetr->msetr_srcname,
1431
+ msetr->msetr_msg_bytes, rd_kafka_q_len(&msetr->msetr_rkq),
1432
+ rktp->rktp_rkt->rkt_topic->str, rktp->rktp_partition,
1433
+ rd_kafka_q_len(msetr->msetr_par_rkq),
1434
+ msetr->msetr_tver->version, last_offset,
1435
+ msetr->msetr_ctrl_cnt, msetr->msetr_aborted_cnt,
1436
+ msetr->msetr_compression
1437
+ ? rd_kafka_compression2str(msetr->msetr_compression)
1438
+ : "uncompressed");
1439
+
1440
+ /* Concat all messages&errors onto the parent's queue
1441
+ * (the partition's fetch queue) */
1442
+ if (rd_kafka_q_concat(msetr->msetr_par_rkq, &msetr->msetr_rkq) != -1) {
1443
+ /* Update partition's fetch offset based on
1444
+ * last message's offest. */
1445
+ if (likely(last_offset != -1))
1446
+ rktp->rktp_offsets.fetch_pos.offset = last_offset + 1;
1447
+ }
1448
+
1449
+ /* Adjust next fetch offset if outlier code has indicated
1450
+ * an even later next offset. */
1451
+ if (msetr->msetr_next_offset > rktp->rktp_offsets.fetch_pos.offset)
1452
+ rktp->rktp_offsets.fetch_pos.offset = msetr->msetr_next_offset;
1453
+
1454
+ rktp->rktp_offsets.fetch_pos.leader_epoch = msetr->msetr_leader_epoch;
1455
+
1456
+ rd_kafka_q_destroy_owner(&msetr->msetr_rkq);
1457
+
1458
+ /* Skip remaining part of slice so caller can continue
1459
+ * with next partition. */
1460
+ rd_slice_read(&msetr->msetr_rkbuf->rkbuf_reader, NULL,
1461
+ rd_slice_remains(&msetr->msetr_rkbuf->rkbuf_reader));
1462
+ return err;
1463
+ }
1464
+
1465
+
1466
+
1467
+ /**
1468
+ * @brief Parse one MessageSet at the current buffer read position,
1469
+ * enqueueing messages, propagating errors, etc.
1470
+ * @remark The current rkbuf_reader slice must be limited to the MessageSet size
1471
+ *
1472
+ * @returns see rd_kafka_msgset_reader_run()
1473
+ */
1474
+ rd_kafka_resp_err_t
1475
+ rd_kafka_msgset_parse(rd_kafka_buf_t *rkbuf,
1476
+ rd_kafka_buf_t *request,
1477
+ rd_kafka_toppar_t *rktp,
1478
+ rd_kafka_aborted_txns_t *aborted_txns,
1479
+ const struct rd_kafka_toppar_ver *tver) {
1480
+ rd_kafka_msgset_reader_t msetr;
1481
+ rd_kafka_resp_err_t err;
1482
+
1483
+ rd_kafka_msgset_reader_init(&msetr, rkbuf, rktp, tver, aborted_txns,
1484
+ rktp->rktp_fetchq);
1485
+
1486
+ /* Parse and handle the message set */
1487
+ err = rd_kafka_msgset_reader_run(&msetr);
1488
+
1489
+ rd_atomic64_add(&rktp->rktp_c.rx_msgs, msetr.msetr_msgcnt);
1490
+ rd_atomic64_add(&rktp->rktp_c.rx_msg_bytes, msetr.msetr_msg_bytes);
1491
+
1492
+ rd_avg_add(&rktp->rktp_rkt->rkt_avg_batchcnt,
1493
+ (int64_t)msetr.msetr_msgcnt);
1494
+ rd_avg_add(&rktp->rktp_rkt->rkt_avg_batchsize,
1495
+ (int64_t)msetr.msetr_msg_bytes);
1496
+
1497
+ return err;
1498
+ }
1499
+
1500
+
1501
+ /**
1502
+ * @brief Offset comparator
1503
+ */
1504
+ static int rd_kafka_offset_cmp(const void *_a, const void *_b) {
1505
+ const int64_t *a = _a, *b = _b;
1506
+ return (*a > *b) - (*a < *b);
1507
+ }
1508
+
1509
+
1510
+ /**
1511
+ * @brief Pid comparator for rd_kafka_aborted_txn_start_offsets_t
1512
+ */
1513
+ static int rd_kafka_aborted_txn_cmp_by_pid(const void *_a, const void *_b) {
1514
+ const rd_kafka_aborted_txn_start_offsets_t *a = _a, *b = _b;
1515
+ return (a->pid > b->pid) - (a->pid < b->pid);
1516
+ }
1517
+
1518
+
1519
+ /**
1520
+ * @brief Free resources associated with an AVL tree node.
1521
+ */
1522
+ static void rd_kafka_aborted_txn_node_destroy(void *_node_ptr) {
1523
+ rd_kafka_aborted_txn_start_offsets_t *node_ptr = _node_ptr;
1524
+ rd_list_destroy(&node_ptr->offsets);
1525
+ rd_free(node_ptr);
1526
+ }
1527
+
1528
+
1529
+ /**
1530
+ * @brief Allocate memory for, and initialize a new
1531
+ * rd_kafka_aborted_txns_t struct.
1532
+ */
1533
+ rd_kafka_aborted_txns_t *rd_kafka_aborted_txns_new(int32_t txn_cnt) {
1534
+ rd_kafka_aborted_txns_t *aborted_txns;
1535
+ aborted_txns = rd_malloc(sizeof(*aborted_txns));
1536
+ rd_avl_init(&aborted_txns->avl, rd_kafka_aborted_txn_cmp_by_pid, 0);
1537
+ rd_list_init(&aborted_txns->list, txn_cnt,
1538
+ rd_kafka_aborted_txn_node_destroy);
1539
+ aborted_txns->cnt = txn_cnt;
1540
+ return aborted_txns;
1541
+ }
1542
+
1543
+
1544
+ /**
1545
+ * @brief Free all resources associated with a
1546
+ * rd_kafka_aborted_txns_t struct.
1547
+ */
1548
+ void rd_kafka_aborted_txns_destroy(rd_kafka_aborted_txns_t *aborted_txns) {
1549
+ rd_list_destroy(&aborted_txns->list);
1550
+ rd_avl_destroy(&aborted_txns->avl);
1551
+ rd_free(aborted_txns);
1552
+ }
1553
+
1554
+
1555
+ /**
1556
+ * @brief Get the abort txn start offsets corresponding to
1557
+ * the specified pid.
1558
+ */
1559
+ static RD_INLINE rd_kafka_aborted_txn_start_offsets_t *
1560
+ rd_kafka_aborted_txns_offsets_for_pid(rd_kafka_aborted_txns_t *aborted_txns,
1561
+ int64_t pid) {
1562
+ rd_kafka_aborted_txn_start_offsets_t node;
1563
+ node.pid = pid;
1564
+ return RD_AVL_FIND(&aborted_txns->avl, &node);
1565
+ }
1566
+
1567
+
1568
+ /**
1569
+ * @brief Get the next aborted transaction start
1570
+ * offset for the specified pid.
1571
+ *
1572
+ * @param increment_idx if true, the offset index will be incremented.
1573
+ * @param max_offset If the next aborted offset is greater than \p max_offset
1574
+ * then the index is not incremented (regardless of
1575
+ * \p increment_idx) and the function returns -1.
1576
+ * This may be the case for empty aborted transactions
1577
+ * that have an ABORT marker but are not listed in the
1578
+ * AbortedTxns list.
1579
+ *
1580
+ *
1581
+ * @returns the start offset or -1 if there is none.
1582
+ */
1583
+ static int64_t
1584
+ rd_kafka_aborted_txns_next_offset(rd_kafka_aborted_txns_t *aborted_txns,
1585
+ int64_t pid,
1586
+ rd_bool_t increment_idx,
1587
+ int64_t max_offset) {
1588
+ int64_t abort_start_offset;
1589
+ rd_kafka_aborted_txn_start_offsets_t *node_ptr =
1590
+ rd_kafka_aborted_txns_offsets_for_pid(aborted_txns, pid);
1591
+
1592
+ if (node_ptr == NULL)
1593
+ return -1;
1594
+
1595
+ if (unlikely(node_ptr->offsets_idx >= rd_list_cnt(&node_ptr->offsets)))
1596
+ return -1;
1597
+
1598
+ abort_start_offset = *(
1599
+ (int64_t *)rd_list_elem(&node_ptr->offsets, node_ptr->offsets_idx));
1600
+
1601
+ if (unlikely(abort_start_offset > max_offset))
1602
+ return -1;
1603
+
1604
+ if (increment_idx)
1605
+ node_ptr->offsets_idx++;
1606
+
1607
+ return abort_start_offset;
1608
+ }
1609
+
1610
+
1611
+ /**
1612
+ * @brief Get the next aborted transaction start
1613
+ * offset for the specified pid and progress the
1614
+ * current index to the next one.
1615
+ *
1616
+ * @param max_offset If the next aborted offset is greater than \p max_offset
1617
+ * then no offset is popped and the function returns -1.
1618
+ * This may be the case for empty aborted transactions
1619
+ * that have an ABORT marker but are not listed in the
1620
+ * AbortedTxns list.
1621
+ *
1622
+ * @returns the start offset or -1 if there is none.
1623
+ */
1624
+ static RD_INLINE int64_t
1625
+ rd_kafka_aborted_txns_pop_offset(rd_kafka_aborted_txns_t *aborted_txns,
1626
+ int64_t pid,
1627
+ int64_t max_offset) {
1628
+ return rd_kafka_aborted_txns_next_offset(aborted_txns, pid, rd_true,
1629
+ max_offset);
1630
+ }
1631
+
1632
+
1633
+ /**
1634
+ * @brief Get the next aborted transaction start
1635
+ * offset for the specified pid.
1636
+ *
1637
+ * @returns the start offset or -1 if there is none.
1638
+ */
1639
+ static RD_INLINE int64_t
1640
+ rd_kafka_aborted_txns_get_offset(const rd_kafka_aborted_txns_t *aborted_txns,
1641
+ int64_t pid) {
1642
+ return rd_kafka_aborted_txns_next_offset(
1643
+ (rd_kafka_aborted_txns_t *)aborted_txns, pid, rd_false, INT64_MAX);
1644
+ }
1645
+
1646
+
1647
+ /**
1648
+ * @brief Add a transaction start offset corresponding
1649
+ * to the specified pid to the aborted_txns collection.
1650
+ */
1651
+ void rd_kafka_aborted_txns_add(rd_kafka_aborted_txns_t *aborted_txns,
1652
+ int64_t pid,
1653
+ int64_t first_offset) {
1654
+ int64_t *v;
1655
+ rd_kafka_aborted_txn_start_offsets_t *node_ptr =
1656
+ rd_kafka_aborted_txns_offsets_for_pid(aborted_txns, pid);
1657
+
1658
+ if (!node_ptr) {
1659
+ node_ptr = rd_malloc(sizeof(*node_ptr));
1660
+ node_ptr->pid = pid;
1661
+ node_ptr->offsets_idx = 0;
1662
+ rd_list_init(&node_ptr->offsets, 0, NULL);
1663
+ /* Each PID list has no more than AbortedTxnCnt elements */
1664
+ rd_list_prealloc_elems(&node_ptr->offsets, sizeof(int64_t),
1665
+ aborted_txns->cnt, 0);
1666
+ RD_AVL_INSERT(&aborted_txns->avl, node_ptr, avl_node);
1667
+ rd_list_add(&aborted_txns->list, node_ptr);
1668
+ }
1669
+
1670
+ v = rd_list_add(&node_ptr->offsets, NULL);
1671
+ *v = first_offset;
1672
+ }
1673
+
1674
+
1675
+ /**
1676
+ * @brief Sort each of the abort transaction start
1677
+ * offset lists for each pid.
1678
+ */
1679
+ void rd_kafka_aborted_txns_sort(rd_kafka_aborted_txns_t *aborted_txns) {
1680
+ int k;
1681
+ for (k = 0; k < rd_list_cnt(&aborted_txns->list); k++) {
1682
+ rd_kafka_aborted_txn_start_offsets_t *el =
1683
+ rd_list_elem(&aborted_txns->list, k);
1684
+ rd_list_sort(&el->offsets, rd_kafka_offset_cmp);
1685
+ }
1686
+ }
1687
+
1688
+
1689
+ /**
1690
+ * @brief Unit tests for all functions that operate on
1691
+ * rd_kafka_aborted_txns_t
1692
+ */
1693
+ int unittest_aborted_txns(void) {
1694
+ rd_kafka_aborted_txns_t *aborted_txns = NULL;
1695
+ int64_t start_offset;
1696
+
1697
+ aborted_txns = rd_kafka_aborted_txns_new(7);
1698
+ rd_kafka_aborted_txns_add(aborted_txns, 1, 42);
1699
+ rd_kafka_aborted_txns_add(aborted_txns, 1, 44);
1700
+ rd_kafka_aborted_txns_add(aborted_txns, 1, 10);
1701
+ rd_kafka_aborted_txns_add(aborted_txns, 1, 100);
1702
+ rd_kafka_aborted_txns_add(aborted_txns, 2, 11);
1703
+ rd_kafka_aborted_txns_add(aborted_txns, 2, 7);
1704
+ rd_kafka_aborted_txns_add(aborted_txns, 1, 3);
1705
+ rd_kafka_aborted_txns_sort(aborted_txns);
1706
+
1707
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
1708
+ RD_UT_ASSERT(3 == start_offset,
1709
+ "queried start offset was %" PRId64
1710
+ ", "
1711
+ "expected 3",
1712
+ start_offset);
1713
+
1714
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
1715
+ RD_UT_ASSERT(3 == start_offset,
1716
+ "queried start offset was %" PRId64
1717
+ ", "
1718
+ "expected 3",
1719
+ start_offset);
1720
+
1721
+ start_offset =
1722
+ rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
1723
+ RD_UT_ASSERT(3 == start_offset,
1724
+ "queried start offset was %" PRId64
1725
+ ", "
1726
+ "expected 3",
1727
+ start_offset);
1728
+
1729
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
1730
+ RD_UT_ASSERT(10 == start_offset,
1731
+ "queried start offset was %" PRId64
1732
+ ", "
1733
+ "expected 10",
1734
+ start_offset);
1735
+
1736
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
1737
+ RD_UT_ASSERT(7 == start_offset,
1738
+ "queried start offset was %" PRId64
1739
+ ", "
1740
+ "expected 7",
1741
+ start_offset);
1742
+
1743
+ rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
1744
+
1745
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
1746
+ RD_UT_ASSERT(42 == start_offset,
1747
+ "queried start offset was %" PRId64
1748
+ ", "
1749
+ "expected 42",
1750
+ start_offset);
1751
+
1752
+ rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
1753
+
1754
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
1755
+ RD_UT_ASSERT(44 == start_offset,
1756
+ "queried start offset was %" PRId64
1757
+ ", "
1758
+ "expected 44",
1759
+ start_offset);
1760
+
1761
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
1762
+ RD_UT_ASSERT(7 == start_offset,
1763
+ "queried start offset was %" PRId64
1764
+ ", "
1765
+ "expected 7",
1766
+ start_offset);
1767
+
1768
+ rd_kafka_aborted_txns_pop_offset(aborted_txns, 2, INT64_MAX);
1769
+
1770
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
1771
+ RD_UT_ASSERT(11 == start_offset,
1772
+ "queried start offset was %" PRId64
1773
+ ", "
1774
+ "expected 11",
1775
+ start_offset);
1776
+
1777
+ /* error cases */
1778
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 3);
1779
+ RD_UT_ASSERT(-1 == start_offset,
1780
+ "queried start offset was %" PRId64
1781
+ ", "
1782
+ "expected -1",
1783
+ start_offset);
1784
+
1785
+ rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
1786
+ rd_kafka_aborted_txns_pop_offset(aborted_txns, 1, INT64_MAX);
1787
+ rd_kafka_aborted_txns_pop_offset(aborted_txns, 2, INT64_MAX);
1788
+
1789
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 1);
1790
+ RD_UT_ASSERT(-1 == start_offset,
1791
+ "queried start offset was %" PRId64
1792
+ ", "
1793
+ "expected -1",
1794
+ start_offset);
1795
+
1796
+ start_offset = rd_kafka_aborted_txns_get_offset(aborted_txns, 2);
1797
+ RD_UT_ASSERT(-1 == start_offset,
1798
+ "queried start offset was %" PRId64
1799
+ ", "
1800
+ "expected -1",
1801
+ start_offset);
1802
+
1803
+ rd_kafka_aborted_txns_destroy(aborted_txns);
1804
+
1805
+ RD_UT_PASS();
1806
+ }