stackforge 0.6.5__tar.gz → 0.6.6__tar.gz

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 (333) hide show
  1. {stackforge-0.6.5 → stackforge-0.6.6}/Cargo.lock +3 -3
  2. {stackforge-0.6.5 → stackforge-0.6.6}/Cargo.toml +1 -1
  3. {stackforge-0.6.5 → stackforge-0.6.6}/PKG-INFO +20 -6
  4. {stackforge-0.6.5 → stackforge-0.6.6}/README.md +19 -5
  5. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/mod.rs +41 -0
  6. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/table.rs +24 -7
  7. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/tcp_state.rs +26 -3
  8. {stackforge-0.6.5 → stackforge-0.6.6}/src/lib.rs +28 -0
  9. {stackforge-0.6.5 → stackforge-0.6.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  10. {stackforge-0.6.5 → stackforge-0.6.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  11. {stackforge-0.6.5 → stackforge-0.6.6}/.github/workflows/release.yml +0 -0
  12. {stackforge-0.6.5 → stackforge-0.6.6}/.github/workflows/test.yml +0 -0
  13. {stackforge-0.6.5 → stackforge-0.6.6}/.gitignore +0 -0
  14. {stackforge-0.6.5 → stackforge-0.6.6}/.pre-commit-config.yaml +0 -0
  15. {stackforge-0.6.5 → stackforge-0.6.6}/.python-version +0 -0
  16. {stackforge-0.6.5 → stackforge-0.6.6}/CLAUDE.md +0 -0
  17. {stackforge-0.6.5 → stackforge-0.6.6}/CODE_OF_CONDUCT.md +0 -0
  18. {stackforge-0.6.5 → stackforge-0.6.6}/CONTRIBUTING.md +0 -0
  19. {stackforge-0.6.5 → stackforge-0.6.6}/LICENSE +0 -0
  20. {stackforge-0.6.5 → stackforge-0.6.6}/cliff.toml +0 -0
  21. {stackforge-0.6.5 → stackforge-0.6.6}/cog.toml +0 -0
  22. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-automata/Cargo.toml +0 -0
  23. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-automata/src/lib.rs +0 -0
  24. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/Cargo.toml +0 -0
  25. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/.DS_Store +0 -0
  26. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/error.rs +0 -0
  27. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/config.rs +0 -0
  28. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/error.rs +0 -0
  29. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/icmp_state.rs +0 -0
  30. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/key.rs +0 -0
  31. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/spill.rs +0 -0
  32. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/state.rs +0 -0
  33. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/tcp_reassembly.rs +0 -0
  34. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/flow/udp_state.rs +0 -0
  35. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/arp.rs +0 -0
  36. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/bindings.rs +0 -0
  37. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/bitmap.rs +0 -0
  38. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/builder.rs +0 -0
  39. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/edns.rs +0 -0
  40. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/header.rs +0 -0
  41. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/mod.rs +0 -0
  42. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/query.rs +0 -0
  43. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/rdata.rs +0 -0
  44. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/rr.rs +0 -0
  45. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/svcb.rs +0 -0
  46. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dns/types.rs +0 -0
  47. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/builder.rs +0 -0
  48. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/control.rs +0 -0
  49. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/data.rs +0 -0
  50. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/ie.rs +0 -0
  51. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/management.rs +0 -0
  52. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/mod.rs +0 -0
  53. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/radiotap.rs +0 -0
  54. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/security.rs +0 -0
  55. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot11/types.rs +0 -0
  56. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/beacon.rs +0 -0
  57. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/builder.rs +0 -0
  58. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/command.rs +0 -0
  59. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/crc.rs +0 -0
  60. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/mod.rs +0 -0
  61. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/security.rs +0 -0
  62. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/dot15d4/types.rs +0 -0
  63. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ethernet.rs +0 -0
  64. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/field.rs +0 -0
  65. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/field_ext.rs +0 -0
  66. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ftp/builder.rs +0 -0
  67. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ftp/mod.rs +0 -0
  68. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/generic/builder.rs +0 -0
  69. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/generic/mod.rs +0 -0
  70. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/builder.rs +0 -0
  71. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/detection.rs +0 -0
  72. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/mod.rs +0 -0
  73. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/request.rs +0 -0
  74. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http/response.rs +0 -0
  75. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/builder.rs +0 -0
  76. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/frames.rs +0 -0
  77. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/hpack.rs +0 -0
  78. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/http2/mod.rs +0 -0
  79. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/builder.rs +0 -0
  80. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/checksum.rs +0 -0
  81. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/error.rs +0 -0
  82. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/extensions.rs +0 -0
  83. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/mod.rs +0 -0
  84. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmp/types.rs +0 -0
  85. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmpv6/builder.rs +0 -0
  86. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/icmpv6/mod.rs +0 -0
  87. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/imap/builder.rs +0 -0
  88. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/imap/mod.rs +0 -0
  89. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/builder.rs +0 -0
  90. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/checksum.rs +0 -0
  91. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/fragmentation.rs +0 -0
  92. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/header.rs +0 -0
  93. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/mod.rs +0 -0
  94. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/options.rs +0 -0
  95. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/protocol.rs +0 -0
  96. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/routing.rs +0 -0
  97. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv4/ttl.rs +0 -0
  98. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv6/builder.rs +0 -0
  99. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv6/ext_headers.rs +0 -0
  100. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ipv6/mod.rs +0 -0
  101. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/l2tp/builder.rs +0 -0
  102. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/l2tp/mod.rs +0 -0
  103. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mod.rs +0 -0
  104. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/modbus/builder.rs +0 -0
  105. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/modbus/crc.rs +0 -0
  106. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/modbus/mod.rs +0 -0
  107. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqtt/builder.rs +0 -0
  108. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqtt/mod.rs +0 -0
  109. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqttsn/builder.rs +0 -0
  110. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/mqttsn/mod.rs +0 -0
  111. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/neighbor.rs +0 -0
  112. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/pop3/builder.rs +0 -0
  113. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/pop3/mod.rs +0 -0
  114. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/builder.rs +0 -0
  115. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/frames.rs +0 -0
  116. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/headers.rs +0 -0
  117. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/mod.rs +0 -0
  118. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/quic/varint.rs +0 -0
  119. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/raw.rs +0 -0
  120. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/smtp/builder.rs +0 -0
  121. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/smtp/mod.rs +0 -0
  122. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ssh/builder.rs +0 -0
  123. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/ssh/mod.rs +0 -0
  124. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/stack.rs +0 -0
  125. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/builder.rs +0 -0
  126. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/checksum.rs +0 -0
  127. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/flags.rs +0 -0
  128. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/header.rs +0 -0
  129. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/mod.rs +0 -0
  130. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/options.rs +0 -0
  131. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tcp/services.rs +0 -0
  132. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tftp/builder.rs +0 -0
  133. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tftp/mod.rs +0 -0
  134. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/builder.rs +0 -0
  135. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/cert.rs +0 -0
  136. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/cipher_aead.rs +0 -0
  137. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/cipher_block.rs +0 -0
  138. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/cipher_stream.rs +0 -0
  139. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/compression.rs +0 -0
  140. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/groups.rs +0 -0
  141. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/hash.rs +0 -0
  142. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/hkdf_tls13.rs +0 -0
  143. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/hmac_tls.rs +0 -0
  144. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/mod.rs +0 -0
  145. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/prf.rs +0 -0
  146. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/crypto/suites.rs +0 -0
  147. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/common.rs +0 -0
  148. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/key_share.rs +0 -0
  149. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/mod.rs +0 -0
  150. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/signature_algorithms.rs +0 -0
  151. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/sni.rs +0 -0
  152. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/extensions/supported_versions.rs +0 -0
  153. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/certificate.rs +0 -0
  154. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/client_hello.rs +0 -0
  155. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/finished.rs +0 -0
  156. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/key_exchange.rs +0 -0
  157. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/mod.rs +0 -0
  158. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/handshake/server_hello.rs +0 -0
  159. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/keyexchange/ecdhe.rs +0 -0
  160. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/keyexchange/mod.rs +0 -0
  161. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/mod.rs +0 -0
  162. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/record.rs +0 -0
  163. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/session.rs +0 -0
  164. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/sslv2/handshake.rs +0 -0
  165. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/sslv2/mod.rs +0 -0
  166. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/sslv2/record.rs +0 -0
  167. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/tls/types.rs +0 -0
  168. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/udp/builder.rs +0 -0
  169. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/udp/checksum.rs +0 -0
  170. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/udp/mod.rs +0 -0
  171. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/zwave/builder.rs +0 -0
  172. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/layer/zwave/mod.rs +0 -0
  173. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/lib.rs +0 -0
  174. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/packet.rs +0 -0
  175. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/pcap/mod.rs +0 -0
  176. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/pcap/reader.rs +0 -0
  177. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/pcap/writer.rs +0 -0
  178. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/bits.rs +0 -0
  179. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/checksum.rs +0 -0
  180. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/compare.rs +0 -0
  181. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/hex.rs +0 -0
  182. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/mod.rs +0 -0
  183. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/padding.rs +0 -0
  184. {stackforge-0.6.5 → stackforge-0.6.6}/crates/stackforge-core/src/utils/random.rs +0 -0
  185. {stackforge-0.6.5 → stackforge-0.6.6}/pyproject.toml +0 -0
  186. {stackforge-0.6.5 → stackforge-0.6.6}/python/stackforge/__init__.py +0 -0
  187. {stackforge-0.6.5 → stackforge-0.6.6}/python/stackforge/custom.py +0 -0
  188. {stackforge-0.6.5 → stackforge-0.6.6}/rust-toolchain.toml +0 -0
  189. {stackforge-0.6.5 → stackforge-0.6.6}/rustfmt.toml +0 -0
  190. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/arp.rs +0 -0
  191. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/arp_compat.rs +0 -0
  192. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/ethernet_compat.rs +0 -0
  193. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/icmp_compat.rs +0 -0
  194. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/ipv4_compat.rs +0 -0
  195. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/mod.rs +0 -0
  196. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/ssh_compat.rs +0 -0
  197. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/tcp_compat.rs +0 -0
  198. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/tls_compat.rs +0 -0
  199. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/compat_tests/udp_compat.rs +0 -0
  200. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/dns.rs +0 -0
  201. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/dot11.rs +0 -0
  202. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/dot15d4.rs +0 -0
  203. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ethernet.rs +0 -0
  204. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/field.rs +0 -0
  205. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ftp.rs +0 -0
  206. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/http.rs +0 -0
  207. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/http2.rs +0 -0
  208. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/icmpv6.rs +0 -0
  209. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/imap.rs +0 -0
  210. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ipv6.rs +0 -0
  211. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/layer.rs +0 -0
  212. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/main.rs +0 -0
  213. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/modbus.rs +0 -0
  214. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/mqtt.rs +0 -0
  215. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/packet.rs +0 -0
  216. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/pop3.rs +0 -0
  217. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/quic.rs +0 -0
  218. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/smtp.rs +0 -0
  219. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/ssh.rs +0 -0
  220. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/tftp.rs +0 -0
  221. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/tls.rs +0 -0
  222. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/util.rs +0 -0
  223. {stackforge-0.6.5 → stackforge-0.6.6}/tests/integration/zwave.rs +0 -0
  224. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/__init__.py +0 -0
  225. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/conftest.py +0 -0
  226. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_arp_compat.py +0 -0
  227. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_checksums_compat.py +0 -0
  228. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_edge_cases_compat.py +0 -0
  229. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_ethernet_compat.py +0 -0
  230. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_icmp_compat.py +0 -0
  231. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_ipv4_compat.py +0 -0
  232. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_pcap_compat.py +0 -0
  233. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_stacking_compat.py +0 -0
  234. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_tcp_compat.py +0 -0
  235. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_udp_compat.py +0 -0
  236. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/scapy_compat/test_uts_integration.py +0 -0
  237. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_core.py +0 -0
  238. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_custom.py +0 -0
  239. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_dns.py +0 -0
  240. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_dot11.py +0 -0
  241. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_dot15d4.py +0 -0
  242. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_flow.py +0 -0
  243. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_ftp.py +0 -0
  244. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_http.py +0 -0
  245. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_icmpv6.py +0 -0
  246. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_imap.py +0 -0
  247. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_ipv6.py +0 -0
  248. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_l2tp.py +0 -0
  249. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_max_packet_flow_len.py +0 -0
  250. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_modbus.py +0 -0
  251. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_mqtt.py +0 -0
  252. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_mqttsn.py +0 -0
  253. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_pcap.py +0 -0
  254. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_pcapng.py +0 -0
  255. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_pop3.py +0 -0
  256. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_quic.py +0 -0
  257. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_smtp.py +0 -0
  258. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_ssh.py +0 -0
  259. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_streaming_flows.py +0 -0
  260. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_tftp.py +0 -0
  261. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_tls.py +0 -0
  262. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_udp_icmp.py +0 -0
  263. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_ftp.py +0 -0
  264. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_http.py +0 -0
  265. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_http2.py +0 -0
  266. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_imap.py +0 -0
  267. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_ipv6.py +0 -0
  268. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_l2tp.py +0 -0
  269. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_modbus.py +0 -0
  270. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_mqtt.py +0 -0
  271. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_mqttsn.py +0 -0
  272. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_pop3.py +0 -0
  273. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_quic.py +0 -0
  274. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_smtp.py +0 -0
  275. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_tftp.py +0 -0
  276. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_uts_zwave.py +0 -0
  277. {stackforge-0.6.5 → stackforge-0.6.6}/tests/python/test_zwave.py +0 -0
  278. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http2_h2c.pcap +0 -0
  279. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_chunk.pcap +0 -0
  280. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_compressed-brotli.pcap +0 -0
  281. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_compressed-zstd.pcap +0 -0
  282. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_compressed.pcap +0 -0
  283. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_content_length.pcap +0 -0
  284. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_head.pcapng +0 -0
  285. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/http_tcp_psh.pcap +0 -0
  286. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/ssh_ed25519.pcap +0 -0
  287. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/tcprelay/PCAP.md +0 -0
  288. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/tcprelay/smallFlows.pcap +0 -0
  289. {stackforge-0.6.5 → stackforge-0.6.6}/tests/sample_pcap/tcprelay/test.pcap +0 -0
  290. {stackforge-0.6.5 → stackforge-0.6.6}/tests/scripts/compare_packets.py +0 -0
  291. {stackforge-0.6.5 → stackforge-0.6.6}/tests/scripts/generate_scapy_fixtures.py +0 -0
  292. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dns.uts +0 -0
  293. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dns_dnssec.uts +0 -0
  294. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dns_edns0.uts +0 -0
  295. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dot11.uts +0 -0
  296. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/dot15d4.uts +0 -0
  297. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/fields.uts +0 -0
  298. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/ftp.uts +0 -0
  299. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/http.uts +0 -0
  300. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/http2.uts +0 -0
  301. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/imap.uts +0 -0
  302. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/inet.uts +0 -0
  303. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/inet6 copy.uts +0 -0
  304. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/inet6.uts +0 -0
  305. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/l2.uts +0 -0
  306. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/l2tp.uts +0 -0
  307. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/modbus.uts +0 -0
  308. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/mqtt.uts +0 -0
  309. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/mqttsn.uts +0 -0
  310. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/pop3.uts +0 -0
  311. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/quic.uts +0 -0
  312. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/smtp.uts +0 -0
  313. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/ssh.uts +0 -0
  314. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tftp.uts +0 -0
  315. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/__init__.py +0 -0
  316. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/cert.uts +0 -0
  317. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/example_client.py +0 -0
  318. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/example_server.py +0 -0
  319. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/README.md +0 -0
  320. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/ca_cert.pem +0 -0
  321. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/ca_key.pem +0 -0
  322. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/cli_cert.pem +0 -0
  323. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/cli_key.pem +0 -0
  324. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_cert.pem +0 -0
  325. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_cert_ed25519.pem +0 -0
  326. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_key.pem +0 -0
  327. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/pki/srv_key_ed25519.pem +0 -0
  328. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/sslv2.uts +0 -0
  329. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/tls.uts +0 -0
  330. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/tls13.uts +0 -0
  331. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/tls/tlsclientserver.uts +0 -0
  332. {stackforge-0.6.5 → stackforge-0.6.6}/tests/uts/zwave.uts +0 -0
  333. {stackforge-0.6.5 → stackforge-0.6.6}/uv.lock +0 -0
@@ -1074,7 +1074,7 @@ dependencies = [
1074
1074
 
1075
1075
  [[package]]
1076
1076
  name = "stackforge"
1077
- version = "0.6.5"
1077
+ version = "0.6.6"
1078
1078
  dependencies = [
1079
1079
  "pyo3",
1080
1080
  "stackforge-automata",
@@ -1083,7 +1083,7 @@ dependencies = [
1083
1083
 
1084
1084
  [[package]]
1085
1085
  name = "stackforge-automata"
1086
- version = "0.6.5"
1086
+ version = "0.6.6"
1087
1087
  dependencies = [
1088
1088
  "bytes",
1089
1089
  "stackforge-core",
@@ -1091,7 +1091,7 @@ dependencies = [
1091
1091
 
1092
1092
  [[package]]
1093
1093
  name = "stackforge-core"
1094
- version = "0.6.5"
1094
+ version = "0.6.6"
1095
1095
  dependencies = [
1096
1096
  "aes",
1097
1097
  "aes-gcm",
@@ -21,7 +21,7 @@ shared-version = true
21
21
  tag-name = "v{{version}}"
22
22
 
23
23
  [workspace.package]
24
- version = "0.6.5"
24
+ version = "0.6.6"
25
25
  edition = "2024"
26
26
  license = "GPL-3.0-only"
27
27
  authors = ["Stackforge Contributors"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stackforge
3
- Version: 0.6.5
3
+ Version: 0.6.6
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Intended Audience :: System Administrators
@@ -359,17 +359,29 @@ Enable verbose mode to see progress feedback on stderr during extraction:
359
359
  ```python
360
360
  # Quick verbose flag on the function call
361
361
  conversations = extract_flows("capture.pcap", verbose=True)
362
- # [stackforge] Opening capture file: capture.pcap
363
- # [stackforge] Starting streaming flow extraction...
364
- # [stackforge] Processed 10000 packets (342 flows so far)
365
- # [stackforge] Processed 20000 packets (587 flows so far)
366
- # [stackforge] Flow extraction complete: 612 conversations
367
362
 
368
363
  # Or via FlowConfig
369
364
  config = FlowConfig(verbose=True)
370
365
  conversations = extract_flows("capture.pcap", config=config)
371
366
  ```
372
367
 
368
+ Verbose output shows real-time progress with processing rate, memory usage, ETA, and spill stats:
369
+
370
+ ```
371
+ [+] stackforge flow extraction engine
372
+ [+] File: capture.pcap (2.3 GB)
373
+ [+] Mode: streaming (packets read from disk on-the-fly)
374
+ [+] Memory budget: 1.00 GB
375
+ [+] Processing...
376
+
377
+ [1m 23s] 100,000 pkts | 1,234 flows | 85,432/s (avg 72,150/s) | mem ~45.2 MB
378
+ [2m 48s] 200,000 pkts | 2,567 flows | 78,901/s (avg 71,428/s) | mem ~89.1 MB | 3 spills
379
+
380
+ [+] Finalizing (sorting 88,254 flows)...
381
+ [+] Complete: 88,254 flows extracted
382
+ [+] Wall time: 1h 12m
383
+ ```
384
+
373
385
  Customize timeouts, buffer limits, and memory budget with `FlowConfig`:
374
386
 
375
387
  ```python
@@ -389,6 +401,8 @@ For large captures, set a memory budget so reassembly buffers automatically spil
389
401
  config = FlowConfig(
390
402
  memory_budget=256 * 1024 * 1024, # 256 MB RAM budget
391
403
  spill_dir="/tmp/stackforge-spill", # optional custom spill directory
404
+ store_packet_indices=False, # save ~8 bytes/pkt on large captures
405
+ progress_interval=500_000, # report every 500K packets (default: 100K)
392
406
  )
393
407
  conversations = extract_flows("large_capture.pcapng", config=config)
394
408
  ```
@@ -335,17 +335,29 @@ Enable verbose mode to see progress feedback on stderr during extraction:
335
335
  ```python
336
336
  # Quick verbose flag on the function call
337
337
  conversations = extract_flows("capture.pcap", verbose=True)
338
- # [stackforge] Opening capture file: capture.pcap
339
- # [stackforge] Starting streaming flow extraction...
340
- # [stackforge] Processed 10000 packets (342 flows so far)
341
- # [stackforge] Processed 20000 packets (587 flows so far)
342
- # [stackforge] Flow extraction complete: 612 conversations
343
338
 
344
339
  # Or via FlowConfig
345
340
  config = FlowConfig(verbose=True)
346
341
  conversations = extract_flows("capture.pcap", config=config)
347
342
  ```
348
343
 
344
+ Verbose output shows real-time progress with processing rate, memory usage, ETA, and spill stats:
345
+
346
+ ```
347
+ [+] stackforge flow extraction engine
348
+ [+] File: capture.pcap (2.3 GB)
349
+ [+] Mode: streaming (packets read from disk on-the-fly)
350
+ [+] Memory budget: 1.00 GB
351
+ [+] Processing...
352
+
353
+ [1m 23s] 100,000 pkts | 1,234 flows | 85,432/s (avg 72,150/s) | mem ~45.2 MB
354
+ [2m 48s] 200,000 pkts | 2,567 flows | 78,901/s (avg 71,428/s) | mem ~89.1 MB | 3 spills
355
+
356
+ [+] Finalizing (sorting 88,254 flows)...
357
+ [+] Complete: 88,254 flows extracted
358
+ [+] Wall time: 1h 12m
359
+ ```
360
+
349
361
  Customize timeouts, buffer limits, and memory budget with `FlowConfig`:
350
362
 
351
363
  ```python
@@ -365,6 +377,8 @@ For large captures, set a memory budget so reassembly buffers automatically spil
365
377
  config = FlowConfig(
366
378
  memory_budget=256 * 1024 * 1024, # 256 MB RAM budget
367
379
  spill_dir="/tmp/stackforge-spill", # optional custom spill directory
380
+ store_packet_indices=False, # save ~8 bytes/pkt on large captures
381
+ progress_interval=500_000, # report every 500K packets (default: 100K)
368
382
  )
369
383
  conversations = extract_flows("large_capture.pcapng", config=config)
370
384
  ```
@@ -174,6 +174,18 @@ pub fn extract_flows_with_config(
174
174
  format_duration(elapsed),
175
175
  format_count(rate as usize)
176
176
  );
177
+
178
+ let (total_drops, flows_with_drops) = count_dropped_segments(&conversations);
179
+ if total_drops > 0 {
180
+ eprintln!(
181
+ "[!] Warning: {} TCP segments dropped across {} flows (buffer/fragment limits exceeded)",
182
+ format_count(total_drops as usize),
183
+ format_count(flows_with_drops),
184
+ );
185
+ eprintln!(
186
+ "[!] Tip: increase max_reassembly_buffer or max_ooo_fragments to capture more data"
187
+ );
188
+ }
177
189
  eprintln!();
178
190
  }
179
191
  Ok(conversations)
@@ -265,11 +277,40 @@ where
265
277
  format_count(conversations.len())
266
278
  );
267
279
  eprintln!("[+] Wall time: {}", format_duration(elapsed));
280
+
281
+ // Report reassembly drops
282
+ let (total_drops, flows_with_drops) = count_dropped_segments(&conversations);
283
+ if total_drops > 0 {
284
+ eprintln!(
285
+ "[!] Warning: {} TCP segments dropped across {} flows (buffer/fragment limits exceeded)",
286
+ format_count(total_drops as usize),
287
+ format_count(flows_with_drops),
288
+ );
289
+ eprintln!(
290
+ "[!] Tip: increase max_reassembly_buffer or max_ooo_fragments to capture more data"
291
+ );
292
+ }
268
293
  eprintln!();
269
294
  }
270
295
  Ok(conversations)
271
296
  }
272
297
 
298
+ /// Count total dropped TCP segments across all conversations.
299
+ fn count_dropped_segments(conversations: &[ConversationState]) -> (u64, usize) {
300
+ let mut total_drops: u64 = 0;
301
+ let mut flows_with_drops: usize = 0;
302
+ for conv in conversations {
303
+ if let ProtocolState::Tcp(ref tcp) = conv.protocol_state {
304
+ let drops = tcp.total_dropped_segments();
305
+ if drops > 0 {
306
+ total_drops += drops;
307
+ flows_with_drops += 1;
308
+ }
309
+ }
310
+ }
311
+ (total_drops, flows_with_drops)
312
+ }
313
+
273
314
  /// Extract flows directly from a capture file (PCAP or PcapNG).
274
315
  ///
275
316
  /// Streams packets from disk — never loads the entire file into memory.
@@ -160,20 +160,31 @@ impl ConversationTable {
160
160
 
161
161
  /// Spill reassembly buffers to disk until under budget.
162
162
  ///
163
- /// Limits the number of entries scanned per call to avoid O(n) full-table
164
- /// walks that become expensive as the flow count grows.
163
+ /// Two limits prevent runaway iteration:
164
+ /// - `max_spills`: stop after spilling this many buffers (actual work done)
165
+ /// - `max_skip`: stop after skipping this many already-spilled/non-TCP entries
166
+ /// without finding anything to free (avoids scanning the entire table when
167
+ /// most flows are already on disk)
165
168
  fn maybe_spill(&self) {
166
- let mut scanned = 0;
167
- let max_scan = 256; // Cap per-call work to avoid stalls
169
+ let mut spills = 0;
170
+ let max_spills = 64;
171
+ let mut consecutive_skips = 0;
172
+ let max_skip = 512;
173
+
168
174
  for mut entry in self.conversations.iter_mut() {
169
- if !self.memory_tracker.is_over_budget() || scanned >= max_scan {
175
+ if !self.memory_tracker.is_over_budget() || spills >= max_spills {
176
+ break;
177
+ }
178
+ if consecutive_skips >= max_skip {
179
+ // Most nearby entries are already spilled — stop scanning
170
180
  break;
171
181
  }
172
- scanned += 1;
182
+
173
183
  if let ProtocolState::Tcp(ref mut tcp_state) = entry.value_mut().protocol_state {
174
- // Only try to spill buffers that are still in memory
184
+ // Skip buffers already on disk
175
185
  if tcp_state.reassembler_fwd.is_spilled() && tcp_state.reassembler_rev.is_spilled()
176
186
  {
187
+ consecutive_skips += 1;
177
188
  continue;
178
189
  }
179
190
  let freed_fwd = tcp_state
@@ -189,7 +200,13 @@ impl ConversationTable {
189
200
  self.memory_tracker.subtract(total_freed);
190
201
  self.spill_count
191
202
  .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
203
+ spills += 1;
204
+ consecutive_skips = 0; // Reset — we found something useful
205
+ } else {
206
+ consecutive_skips += 1;
192
207
  }
208
+ } else {
209
+ consecutive_skips += 1;
193
210
  }
194
211
  }
195
212
  }
@@ -104,6 +104,10 @@ pub struct TcpConversationState {
104
104
  pub reassembler_fwd: TcpReassembler,
105
105
  /// Stream reassembly for reverse direction.
106
106
  pub reassembler_rev: TcpReassembler,
107
+ /// Number of forward segments dropped due to buffer/fragment limits.
108
+ pub dropped_segments_fwd: u64,
109
+ /// Number of reverse segments dropped due to buffer/fragment limits.
110
+ pub dropped_segments_rev: u64,
107
111
  }
108
112
 
109
113
  impl TcpConversationState {
@@ -115,9 +119,17 @@ impl TcpConversationState {
115
119
  reverse_endpoint: TcpEndpointState::new(),
116
120
  reassembler_fwd: TcpReassembler::new(),
117
121
  reassembler_rev: TcpReassembler::new(),
122
+ dropped_segments_fwd: 0,
123
+ dropped_segments_rev: 0,
118
124
  }
119
125
  }
120
126
 
127
+ /// Total dropped segments across both directions.
128
+ #[must_use]
129
+ pub fn total_dropped_segments(&self) -> u64 {
130
+ self.dropped_segments_fwd + self.dropped_segments_rev
131
+ }
132
+
121
133
  /// Process a TCP packet, updating connection state and reassembly buffers.
122
134
  ///
123
135
  /// `direction` indicates whether this packet is Forward (`addr_a` → `addr_b`)
@@ -219,9 +231,20 @@ impl TcpConversationState {
219
231
 
220
232
  // Process payload through reassembler
221
233
  if !payload.is_empty() {
222
- // Ignore reassembly errors (buffer full, etc.) — they don't
223
- // affect connection state tracking
224
- let _ = reassembler.process_segment(seq, payload, config);
234
+ if let Err(e) = reassembler.process_segment(seq, payload, config) {
235
+ // Buffer full or too many fragments — track the drop
236
+ match direction {
237
+ FlowDirection::Forward => self.dropped_segments_fwd += 1,
238
+ FlowDirection::Reverse => self.dropped_segments_rev += 1,
239
+ }
240
+ // Log once at thresholds to avoid flooding stderr
241
+ let total = self.dropped_segments_fwd + self.dropped_segments_rev;
242
+ if total == 1 || total.is_power_of_two() {
243
+ eprintln!(
244
+ "[!] stackforge: TCP reassembly dropped segment ({e}), {total} total drops for this flow"
245
+ );
246
+ }
247
+ }
225
248
  }
226
249
 
227
250
  if flags.fin {
@@ -4254,6 +4254,34 @@ impl PyConversation {
4254
4254
  }
4255
4255
  }
4256
4256
 
4257
+ /// Number of TCP segments dropped due to reassembly buffer/fragment limits.
4258
+ /// Returns 0 for non-TCP flows.
4259
+ #[getter]
4260
+ fn dropped_segments(&self) -> u64 {
4261
+ match &self.inner.protocol_state {
4262
+ stackforge_core::ProtocolState::Tcp(tcp) => tcp.total_dropped_segments(),
4263
+ _ => 0,
4264
+ }
4265
+ }
4266
+
4267
+ /// Number of forward-direction TCP segments dropped.
4268
+ #[getter]
4269
+ fn dropped_segments_fwd(&self) -> u64 {
4270
+ match &self.inner.protocol_state {
4271
+ stackforge_core::ProtocolState::Tcp(tcp) => tcp.dropped_segments_fwd,
4272
+ _ => 0,
4273
+ }
4274
+ }
4275
+
4276
+ /// Number of reverse-direction TCP segments dropped.
4277
+ #[getter]
4278
+ fn dropped_segments_rev(&self) -> u64 {
4279
+ match &self.inner.protocol_state {
4280
+ stackforge_core::ProtocolState::Tcp(tcp) => tcp.dropped_segments_rev,
4281
+ _ => 0,
4282
+ }
4283
+ }
4284
+
4257
4285
  /// Z-Wave home ID, or None for non-Z-Wave flows.
4258
4286
  #[getter]
4259
4287
  fn zwave_home_id(&self) -> Option<u32> {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes