@serve.zone/dcrouter 2.12.4

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 (737) hide show
  1. package/.dockerignore +1 -0
  2. package/.gitea/workflows/docker_nottags.yaml +71 -0
  3. package/.gitea/workflows/docker_tags.yaml +106 -0
  4. package/.vscode/launch.json +11 -0
  5. package/.vscode/settings.json +26 -0
  6. package/Dockerfile +46 -0
  7. package/changelog.md +247 -0
  8. package/cli.child.js +4 -0
  9. package/cli.child.ts +4 -0
  10. package/cli.js +4 -0
  11. package/cli.ts.js +5 -0
  12. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  13. package/dist_ts/00_commitinfo_data.js +9 -0
  14. package/dist_ts/classes.dcrouter.d.ts +238 -0
  15. package/dist_ts/classes.dcrouter.js +1008 -0
  16. package/dist_ts/config/index.d.ts +1 -0
  17. package/dist_ts/config/index.js +3 -0
  18. package/dist_ts/config/validator.d.ts +104 -0
  19. package/dist_ts/config/validator.js +152 -0
  20. package/dist_ts/deliverability/classes.ipwarmupmanager.d.ts +253 -0
  21. package/dist_ts/deliverability/classes.ipwarmupmanager.js +639 -0
  22. package/dist_ts/deliverability/classes.senderreputationmonitor.d.ts +300 -0
  23. package/dist_ts/deliverability/classes.senderreputationmonitor.js +961 -0
  24. package/dist_ts/deliverability/index.d.ts +2 -0
  25. package/dist_ts/deliverability/index.js +3 -0
  26. package/dist_ts/errors/base.errors.d.ts +224 -0
  27. package/dist_ts/errors/base.errors.js +310 -0
  28. package/dist_ts/errors/email.errors.d.ts +175 -0
  29. package/dist_ts/errors/email.errors.js +265 -0
  30. package/dist_ts/errors/error-handler.d.ts +98 -0
  31. package/dist_ts/errors/error-handler.js +282 -0
  32. package/dist_ts/errors/error.codes.d.ts +115 -0
  33. package/dist_ts/errors/error.codes.js +136 -0
  34. package/dist_ts/errors/index.d.ts +56 -0
  35. package/dist_ts/errors/index.js +138 -0
  36. package/dist_ts/errors/mta.errors.d.ts +259 -0
  37. package/dist_ts/errors/mta.errors.js +472 -0
  38. package/dist_ts/errors/reputation.errors.d.ts +183 -0
  39. package/dist_ts/errors/reputation.errors.js +292 -0
  40. package/dist_ts/index.d.ts +4 -0
  41. package/dist_ts/index.js +6 -0
  42. package/dist_ts/logger.d.ts +17 -0
  43. package/dist_ts/logger.js +77 -0
  44. package/dist_ts/mail/core/classes.bouncemanager.d.ts +200 -0
  45. package/dist_ts/mail/core/classes.bouncemanager.js +778 -0
  46. package/dist_ts/mail/core/classes.email.d.ts +291 -0
  47. package/dist_ts/mail/core/classes.email.js +780 -0
  48. package/dist_ts/mail/core/classes.emailvalidator.d.ts +61 -0
  49. package/dist_ts/mail/core/classes.emailvalidator.js +182 -0
  50. package/dist_ts/mail/core/classes.templatemanager.d.ts +95 -0
  51. package/dist_ts/mail/core/classes.templatemanager.js +239 -0
  52. package/dist_ts/mail/core/index.d.ts +4 -0
  53. package/dist_ts/mail/core/index.js +6 -0
  54. package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
  55. package/dist_ts/mail/delivery/classes.delivery.queue.js +485 -0
  56. package/dist_ts/mail/delivery/classes.delivery.system.d.ts +186 -0
  57. package/dist_ts/mail/delivery/classes.delivery.system.js +846 -0
  58. package/dist_ts/mail/delivery/classes.emailsendjob.d.ts +84 -0
  59. package/dist_ts/mail/delivery/classes.emailsendjob.js +362 -0
  60. package/dist_ts/mail/delivery/classes.emailsignjob.d.ts +18 -0
  61. package/dist_ts/mail/delivery/classes.emailsignjob.js +44 -0
  62. package/dist_ts/mail/delivery/classes.mta.config.d.ts +22 -0
  63. package/dist_ts/mail/delivery/classes.mta.config.js +51 -0
  64. package/dist_ts/mail/delivery/classes.ratelimiter.d.ts +98 -0
  65. package/dist_ts/mail/delivery/classes.ratelimiter.js +205 -0
  66. package/dist_ts/mail/delivery/classes.smtp.client.legacy.d.ts +275 -0
  67. package/dist_ts/mail/delivery/classes.smtp.client.legacy.js +973 -0
  68. package/dist_ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
  69. package/dist_ts/mail/delivery/classes.unified.rate.limiter.js +817 -0
  70. package/dist_ts/mail/delivery/index.d.ts +12 -0
  71. package/dist_ts/mail/delivery/index.js +18 -0
  72. package/dist_ts/mail/delivery/interfaces.d.ts +243 -0
  73. package/dist_ts/mail/delivery/interfaces.js +17 -0
  74. package/dist_ts/mail/delivery/smtpclient/auth-handler.d.ts +43 -0
  75. package/dist_ts/mail/delivery/smtpclient/auth-handler.js +188 -0
  76. package/dist_ts/mail/delivery/smtpclient/command-handler.d.ts +67 -0
  77. package/dist_ts/mail/delivery/smtpclient/command-handler.js +276 -0
  78. package/dist_ts/mail/delivery/smtpclient/connection-manager.d.ts +48 -0
  79. package/dist_ts/mail/delivery/smtpclient/connection-manager.js +238 -0
  80. package/dist_ts/mail/delivery/smtpclient/constants.d.ts +129 -0
  81. package/dist_ts/mail/delivery/smtpclient/constants.js +135 -0
  82. package/dist_ts/mail/delivery/smtpclient/create-client.d.ts +22 -0
  83. package/dist_ts/mail/delivery/smtpclient/create-client.js +86 -0
  84. package/dist_ts/mail/delivery/smtpclient/error-handler.d.ts +28 -0
  85. package/dist_ts/mail/delivery/smtpclient/error-handler.js +110 -0
  86. package/dist_ts/mail/delivery/smtpclient/index.d.ts +16 -0
  87. package/dist_ts/mail/delivery/smtpclient/index.js +21 -0
  88. package/dist_ts/mail/delivery/smtpclient/interfaces.d.ts +183 -0
  89. package/dist_ts/mail/delivery/smtpclient/interfaces.js +19 -0
  90. package/dist_ts/mail/delivery/smtpclient/smtp-client.d.ts +58 -0
  91. package/dist_ts/mail/delivery/smtpclient/smtp-client.js +279 -0
  92. package/dist_ts/mail/delivery/smtpclient/tls-handler.d.ts +33 -0
  93. package/dist_ts/mail/delivery/smtpclient/tls-handler.js +202 -0
  94. package/dist_ts/mail/delivery/smtpclient/utils/helpers.d.ts +77 -0
  95. package/dist_ts/mail/delivery/smtpclient/utils/helpers.js +196 -0
  96. package/dist_ts/mail/delivery/smtpclient/utils/logging.d.ts +46 -0
  97. package/dist_ts/mail/delivery/smtpclient/utils/logging.js +153 -0
  98. package/dist_ts/mail/delivery/smtpclient/utils/validation.d.ts +38 -0
  99. package/dist_ts/mail/delivery/smtpclient/utils/validation.js +139 -0
  100. package/dist_ts/mail/delivery/smtpserver/certificate-utils.d.ts +45 -0
  101. package/dist_ts/mail/delivery/smtpserver/certificate-utils.js +345 -0
  102. package/dist_ts/mail/delivery/smtpserver/command-handler.d.ts +156 -0
  103. package/dist_ts/mail/delivery/smtpserver/command-handler.js +1159 -0
  104. package/dist_ts/mail/delivery/smtpserver/connection-manager.d.ts +159 -0
  105. package/dist_ts/mail/delivery/smtpserver/connection-manager.js +894 -0
  106. package/dist_ts/mail/delivery/smtpserver/constants.d.ts +130 -0
  107. package/dist_ts/mail/delivery/smtpserver/constants.js +162 -0
  108. package/dist_ts/mail/delivery/smtpserver/create-server.d.ts +14 -0
  109. package/dist_ts/mail/delivery/smtpserver/create-server.js +28 -0
  110. package/dist_ts/mail/delivery/smtpserver/data-handler.d.ts +123 -0
  111. package/dist_ts/mail/delivery/smtpserver/data-handler.js +1148 -0
  112. package/dist_ts/mail/delivery/smtpserver/index.d.ts +20 -0
  113. package/dist_ts/mail/delivery/smtpserver/index.js +27 -0
  114. package/dist_ts/mail/delivery/smtpserver/interfaces.d.ts +530 -0
  115. package/dist_ts/mail/delivery/smtpserver/interfaces.js +10 -0
  116. package/dist_ts/mail/delivery/smtpserver/secure-server.d.ts +15 -0
  117. package/dist_ts/mail/delivery/smtpserver/secure-server.js +79 -0
  118. package/dist_ts/mail/delivery/smtpserver/security-handler.d.ts +86 -0
  119. package/dist_ts/mail/delivery/smtpserver/security-handler.js +234 -0
  120. package/dist_ts/mail/delivery/smtpserver/session-manager.d.ts +140 -0
  121. package/dist_ts/mail/delivery/smtpserver/session-manager.js +469 -0
  122. package/dist_ts/mail/delivery/smtpserver/smtp-server.d.ts +137 -0
  123. package/dist_ts/mail/delivery/smtpserver/smtp-server.js +666 -0
  124. package/dist_ts/mail/delivery/smtpserver/starttls-handler.d.ts +21 -0
  125. package/dist_ts/mail/delivery/smtpserver/starttls-handler.js +207 -0
  126. package/dist_ts/mail/delivery/smtpserver/tls-handler.d.ts +66 -0
  127. package/dist_ts/mail/delivery/smtpserver/tls-handler.js +261 -0
  128. package/dist_ts/mail/delivery/smtpserver/utils/adaptive-logging.d.ts +117 -0
  129. package/dist_ts/mail/delivery/smtpserver/utils/adaptive-logging.js +411 -0
  130. package/dist_ts/mail/delivery/smtpserver/utils/helpers.d.ts +78 -0
  131. package/dist_ts/mail/delivery/smtpserver/utils/helpers.js +208 -0
  132. package/dist_ts/mail/delivery/smtpserver/utils/logging.d.ts +106 -0
  133. package/dist_ts/mail/delivery/smtpserver/utils/logging.js +181 -0
  134. package/dist_ts/mail/delivery/smtpserver/utils/validation.d.ts +69 -0
  135. package/dist_ts/mail/delivery/smtpserver/utils/validation.js +360 -0
  136. package/dist_ts/mail/index.d.ts +8 -0
  137. package/dist_ts/mail/index.js +13 -0
  138. package/dist_ts/mail/routing/classes.dns.manager.d.ts +65 -0
  139. package/dist_ts/mail/routing/classes.dns.manager.js +413 -0
  140. package/dist_ts/mail/routing/classes.dnsmanager.d.ts +165 -0
  141. package/dist_ts/mail/routing/classes.dnsmanager.js +430 -0
  142. package/dist_ts/mail/routing/classes.domain.registry.d.ts +54 -0
  143. package/dist_ts/mail/routing/classes.domain.registry.js +118 -0
  144. package/dist_ts/mail/routing/classes.email.config.d.ts +64 -0
  145. package/dist_ts/mail/routing/classes.email.config.js +2 -0
  146. package/dist_ts/mail/routing/classes.email.router.d.ts +171 -0
  147. package/dist_ts/mail/routing/classes.email.router.js +491 -0
  148. package/dist_ts/mail/routing/classes.unified.email.server.d.ts +426 -0
  149. package/dist_ts/mail/routing/classes.unified.email.server.js +1454 -0
  150. package/dist_ts/mail/routing/index.d.ts +5 -0
  151. package/dist_ts/mail/routing/index.js +7 -0
  152. package/dist_ts/mail/routing/interfaces.d.ts +187 -0
  153. package/dist_ts/mail/routing/interfaces.js +2 -0
  154. package/dist_ts/mail/security/classes.dkimcreator.d.ts +68 -0
  155. package/dist_ts/mail/security/classes.dkimcreator.js +346 -0
  156. package/dist_ts/mail/security/classes.dkimverifier.d.ts +46 -0
  157. package/dist_ts/mail/security/classes.dkimverifier.js +317 -0
  158. package/dist_ts/mail/security/classes.dmarcverifier.d.ts +123 -0
  159. package/dist_ts/mail/security/classes.dmarcverifier.js +365 -0
  160. package/dist_ts/mail/security/classes.spfverifier.d.ts +103 -0
  161. package/dist_ts/mail/security/classes.spfverifier.js +492 -0
  162. package/dist_ts/mail/security/index.d.ts +4 -0
  163. package/dist_ts/mail/security/index.js +6 -0
  164. package/dist_ts/opsserver/classes.opsserver.d.ts +14 -0
  165. package/dist_ts/opsserver/classes.opsserver.js +37 -0
  166. package/dist_ts/opsserver/index.d.ts +1 -0
  167. package/dist_ts/opsserver/index.js +2 -0
  168. package/dist_ts/paths.d.ts +14 -0
  169. package/dist_ts/paths.js +39 -0
  170. package/dist_ts/plugins.d.ts +43 -0
  171. package/dist_ts/plugins.js +50 -0
  172. package/dist_ts/security/classes.contentscanner.d.ts +160 -0
  173. package/dist_ts/security/classes.contentscanner.js +634 -0
  174. package/dist_ts/security/classes.ipreputationchecker.d.ts +150 -0
  175. package/dist_ts/security/classes.ipreputationchecker.js +508 -0
  176. package/dist_ts/security/classes.securitylogger.d.ts +140 -0
  177. package/dist_ts/security/classes.securitylogger.js +232 -0
  178. package/dist_ts/security/index.d.ts +3 -0
  179. package/dist_ts/security/index.js +4 -0
  180. package/dist_ts/sms/classes.smsservice.d.ts +15 -0
  181. package/dist_ts/sms/classes.smsservice.js +72 -0
  182. package/dist_ts/sms/config/sms.config.d.ts +93 -0
  183. package/dist_ts/sms/config/sms.config.js +2 -0
  184. package/dist_ts/sms/config/sms.schema.d.ts +5 -0
  185. package/dist_ts/sms/config/sms.schema.js +121 -0
  186. package/dist_ts/sms/index.d.ts +1 -0
  187. package/dist_ts/sms/index.js +2 -0
  188. package/dist_ts/storage/classes.storagemanager.d.ts +82 -0
  189. package/dist_ts/storage/classes.storagemanager.js +341 -0
  190. package/dist_ts/storage/index.d.ts +1 -0
  191. package/dist_ts/storage/index.js +3 -0
  192. package/dist_ts/ts/00_commitinfo_data.d.ts +8 -0
  193. package/dist_ts/ts/00_commitinfo_data.js +9 -0
  194. package/dist_ts/ts/classes.dcrouter.d.ts +238 -0
  195. package/dist_ts/ts/classes.dcrouter.js +1008 -0
  196. package/dist_ts/ts/config/index.d.ts +1 -0
  197. package/dist_ts/ts/config/index.js +3 -0
  198. package/dist_ts/ts/config/validator.d.ts +104 -0
  199. package/dist_ts/ts/config/validator.js +152 -0
  200. package/dist_ts/ts/deliverability/classes.ipwarmupmanager.d.ts +253 -0
  201. package/dist_ts/ts/deliverability/classes.ipwarmupmanager.js +639 -0
  202. package/dist_ts/ts/deliverability/classes.senderreputationmonitor.d.ts +300 -0
  203. package/dist_ts/ts/deliverability/classes.senderreputationmonitor.js +961 -0
  204. package/dist_ts/ts/deliverability/index.d.ts +2 -0
  205. package/dist_ts/ts/deliverability/index.js +3 -0
  206. package/dist_ts/ts/errors/base.errors.d.ts +224 -0
  207. package/dist_ts/ts/errors/base.errors.js +310 -0
  208. package/dist_ts/ts/errors/email.errors.d.ts +175 -0
  209. package/dist_ts/ts/errors/email.errors.js +265 -0
  210. package/dist_ts/ts/errors/error-handler.d.ts +98 -0
  211. package/dist_ts/ts/errors/error-handler.js +282 -0
  212. package/dist_ts/ts/errors/error.codes.d.ts +115 -0
  213. package/dist_ts/ts/errors/error.codes.js +136 -0
  214. package/dist_ts/ts/errors/index.d.ts +56 -0
  215. package/dist_ts/ts/errors/index.js +138 -0
  216. package/dist_ts/ts/errors/mta.errors.d.ts +259 -0
  217. package/dist_ts/ts/errors/mta.errors.js +472 -0
  218. package/dist_ts/ts/errors/reputation.errors.d.ts +183 -0
  219. package/dist_ts/ts/errors/reputation.errors.js +292 -0
  220. package/dist_ts/ts/index.d.ts +4 -0
  221. package/dist_ts/ts/index.js +6 -0
  222. package/dist_ts/ts/logger.d.ts +17 -0
  223. package/dist_ts/ts/logger.js +77 -0
  224. package/dist_ts/ts/mail/core/classes.bouncemanager.d.ts +200 -0
  225. package/dist_ts/ts/mail/core/classes.bouncemanager.js +778 -0
  226. package/dist_ts/ts/mail/core/classes.email.d.ts +291 -0
  227. package/dist_ts/ts/mail/core/classes.email.js +780 -0
  228. package/dist_ts/ts/mail/core/classes.emailvalidator.d.ts +61 -0
  229. package/dist_ts/ts/mail/core/classes.emailvalidator.js +182 -0
  230. package/dist_ts/ts/mail/core/classes.templatemanager.d.ts +95 -0
  231. package/dist_ts/ts/mail/core/classes.templatemanager.js +239 -0
  232. package/dist_ts/ts/mail/core/index.d.ts +4 -0
  233. package/dist_ts/ts/mail/core/index.js +6 -0
  234. package/dist_ts/ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
  235. package/dist_ts/ts/mail/delivery/classes.delivery.queue.js +485 -0
  236. package/dist_ts/ts/mail/delivery/classes.delivery.system.d.ts +186 -0
  237. package/dist_ts/ts/mail/delivery/classes.delivery.system.js +846 -0
  238. package/dist_ts/ts/mail/delivery/classes.emailsendjob.d.ts +84 -0
  239. package/dist_ts/ts/mail/delivery/classes.emailsendjob.js +362 -0
  240. package/dist_ts/ts/mail/delivery/classes.emailsignjob.d.ts +18 -0
  241. package/dist_ts/ts/mail/delivery/classes.emailsignjob.js +44 -0
  242. package/dist_ts/ts/mail/delivery/classes.mta.config.d.ts +22 -0
  243. package/dist_ts/ts/mail/delivery/classes.mta.config.js +51 -0
  244. package/dist_ts/ts/mail/delivery/classes.ratelimiter.d.ts +98 -0
  245. package/dist_ts/ts/mail/delivery/classes.ratelimiter.js +205 -0
  246. package/dist_ts/ts/mail/delivery/classes.smtp.client.legacy.d.ts +275 -0
  247. package/dist_ts/ts/mail/delivery/classes.smtp.client.legacy.js +973 -0
  248. package/dist_ts/ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
  249. package/dist_ts/ts/mail/delivery/classes.unified.rate.limiter.js +817 -0
  250. package/dist_ts/ts/mail/delivery/index.d.ts +12 -0
  251. package/dist_ts/ts/mail/delivery/index.js +18 -0
  252. package/dist_ts/ts/mail/delivery/interfaces.d.ts +243 -0
  253. package/dist_ts/ts/mail/delivery/interfaces.js +17 -0
  254. package/dist_ts/ts/mail/delivery/smtpclient/auth-handler.d.ts +43 -0
  255. package/dist_ts/ts/mail/delivery/smtpclient/auth-handler.js +188 -0
  256. package/dist_ts/ts/mail/delivery/smtpclient/command-handler.d.ts +67 -0
  257. package/dist_ts/ts/mail/delivery/smtpclient/command-handler.js +276 -0
  258. package/dist_ts/ts/mail/delivery/smtpclient/connection-manager.d.ts +48 -0
  259. package/dist_ts/ts/mail/delivery/smtpclient/connection-manager.js +238 -0
  260. package/dist_ts/ts/mail/delivery/smtpclient/constants.d.ts +129 -0
  261. package/dist_ts/ts/mail/delivery/smtpclient/constants.js +135 -0
  262. package/dist_ts/ts/mail/delivery/smtpclient/create-client.d.ts +22 -0
  263. package/dist_ts/ts/mail/delivery/smtpclient/create-client.js +86 -0
  264. package/dist_ts/ts/mail/delivery/smtpclient/error-handler.d.ts +28 -0
  265. package/dist_ts/ts/mail/delivery/smtpclient/error-handler.js +110 -0
  266. package/dist_ts/ts/mail/delivery/smtpclient/index.d.ts +16 -0
  267. package/dist_ts/ts/mail/delivery/smtpclient/index.js +21 -0
  268. package/dist_ts/ts/mail/delivery/smtpclient/interfaces.d.ts +183 -0
  269. package/dist_ts/ts/mail/delivery/smtpclient/interfaces.js +19 -0
  270. package/dist_ts/ts/mail/delivery/smtpclient/smtp-client.d.ts +58 -0
  271. package/dist_ts/ts/mail/delivery/smtpclient/smtp-client.js +279 -0
  272. package/dist_ts/ts/mail/delivery/smtpclient/tls-handler.d.ts +33 -0
  273. package/dist_ts/ts/mail/delivery/smtpclient/tls-handler.js +202 -0
  274. package/dist_ts/ts/mail/delivery/smtpclient/utils/helpers.d.ts +77 -0
  275. package/dist_ts/ts/mail/delivery/smtpclient/utils/helpers.js +196 -0
  276. package/dist_ts/ts/mail/delivery/smtpclient/utils/logging.d.ts +46 -0
  277. package/dist_ts/ts/mail/delivery/smtpclient/utils/logging.js +153 -0
  278. package/dist_ts/ts/mail/delivery/smtpclient/utils/validation.d.ts +38 -0
  279. package/dist_ts/ts/mail/delivery/smtpclient/utils/validation.js +139 -0
  280. package/dist_ts/ts/mail/delivery/smtpserver/certificate-utils.d.ts +45 -0
  281. package/dist_ts/ts/mail/delivery/smtpserver/certificate-utils.js +345 -0
  282. package/dist_ts/ts/mail/delivery/smtpserver/command-handler.d.ts +156 -0
  283. package/dist_ts/ts/mail/delivery/smtpserver/command-handler.js +1159 -0
  284. package/dist_ts/ts/mail/delivery/smtpserver/connection-manager.d.ts +159 -0
  285. package/dist_ts/ts/mail/delivery/smtpserver/connection-manager.js +894 -0
  286. package/dist_ts/ts/mail/delivery/smtpserver/constants.d.ts +130 -0
  287. package/dist_ts/ts/mail/delivery/smtpserver/constants.js +162 -0
  288. package/dist_ts/ts/mail/delivery/smtpserver/create-server.d.ts +14 -0
  289. package/dist_ts/ts/mail/delivery/smtpserver/create-server.js +28 -0
  290. package/dist_ts/ts/mail/delivery/smtpserver/data-handler.d.ts +123 -0
  291. package/dist_ts/ts/mail/delivery/smtpserver/data-handler.js +1148 -0
  292. package/dist_ts/ts/mail/delivery/smtpserver/index.d.ts +20 -0
  293. package/dist_ts/ts/mail/delivery/smtpserver/index.js +27 -0
  294. package/dist_ts/ts/mail/delivery/smtpserver/interfaces.d.ts +530 -0
  295. package/dist_ts/ts/mail/delivery/smtpserver/interfaces.js +10 -0
  296. package/dist_ts/ts/mail/delivery/smtpserver/secure-server.d.ts +15 -0
  297. package/dist_ts/ts/mail/delivery/smtpserver/secure-server.js +79 -0
  298. package/dist_ts/ts/mail/delivery/smtpserver/security-handler.d.ts +86 -0
  299. package/dist_ts/ts/mail/delivery/smtpserver/security-handler.js +234 -0
  300. package/dist_ts/ts/mail/delivery/smtpserver/session-manager.d.ts +140 -0
  301. package/dist_ts/ts/mail/delivery/smtpserver/session-manager.js +469 -0
  302. package/dist_ts/ts/mail/delivery/smtpserver/smtp-server.d.ts +137 -0
  303. package/dist_ts/ts/mail/delivery/smtpserver/smtp-server.js +666 -0
  304. package/dist_ts/ts/mail/delivery/smtpserver/starttls-handler.d.ts +21 -0
  305. package/dist_ts/ts/mail/delivery/smtpserver/starttls-handler.js +207 -0
  306. package/dist_ts/ts/mail/delivery/smtpserver/tls-handler.d.ts +66 -0
  307. package/dist_ts/ts/mail/delivery/smtpserver/tls-handler.js +261 -0
  308. package/dist_ts/ts/mail/delivery/smtpserver/utils/adaptive-logging.d.ts +117 -0
  309. package/dist_ts/ts/mail/delivery/smtpserver/utils/adaptive-logging.js +411 -0
  310. package/dist_ts/ts/mail/delivery/smtpserver/utils/helpers.d.ts +78 -0
  311. package/dist_ts/ts/mail/delivery/smtpserver/utils/helpers.js +208 -0
  312. package/dist_ts/ts/mail/delivery/smtpserver/utils/logging.d.ts +106 -0
  313. package/dist_ts/ts/mail/delivery/smtpserver/utils/logging.js +181 -0
  314. package/dist_ts/ts/mail/delivery/smtpserver/utils/validation.d.ts +69 -0
  315. package/dist_ts/ts/mail/delivery/smtpserver/utils/validation.js +360 -0
  316. package/dist_ts/ts/mail/index.d.ts +8 -0
  317. package/dist_ts/ts/mail/index.js +13 -0
  318. package/dist_ts/ts/mail/routing/classes.dns.manager.d.ts +65 -0
  319. package/dist_ts/ts/mail/routing/classes.dns.manager.js +413 -0
  320. package/dist_ts/ts/mail/routing/classes.dnsmanager.d.ts +165 -0
  321. package/dist_ts/ts/mail/routing/classes.dnsmanager.js +430 -0
  322. package/dist_ts/ts/mail/routing/classes.domain.registry.d.ts +54 -0
  323. package/dist_ts/ts/mail/routing/classes.domain.registry.js +118 -0
  324. package/dist_ts/ts/mail/routing/classes.email.config.d.ts +64 -0
  325. package/dist_ts/ts/mail/routing/classes.email.config.js +2 -0
  326. package/dist_ts/ts/mail/routing/classes.email.router.d.ts +171 -0
  327. package/dist_ts/ts/mail/routing/classes.email.router.js +491 -0
  328. package/dist_ts/ts/mail/routing/classes.unified.email.server.d.ts +426 -0
  329. package/dist_ts/ts/mail/routing/classes.unified.email.server.js +1454 -0
  330. package/dist_ts/ts/mail/routing/index.d.ts +5 -0
  331. package/dist_ts/ts/mail/routing/index.js +7 -0
  332. package/dist_ts/ts/mail/routing/interfaces.d.ts +187 -0
  333. package/dist_ts/ts/mail/routing/interfaces.js +2 -0
  334. package/dist_ts/ts/mail/security/classes.dkimcreator.d.ts +68 -0
  335. package/dist_ts/ts/mail/security/classes.dkimcreator.js +346 -0
  336. package/dist_ts/ts/mail/security/classes.dkimverifier.d.ts +46 -0
  337. package/dist_ts/ts/mail/security/classes.dkimverifier.js +317 -0
  338. package/dist_ts/ts/mail/security/classes.dmarcverifier.d.ts +123 -0
  339. package/dist_ts/ts/mail/security/classes.dmarcverifier.js +365 -0
  340. package/dist_ts/ts/mail/security/classes.spfverifier.d.ts +103 -0
  341. package/dist_ts/ts/mail/security/classes.spfverifier.js +492 -0
  342. package/dist_ts/ts/mail/security/index.d.ts +4 -0
  343. package/dist_ts/ts/mail/security/index.js +6 -0
  344. package/dist_ts/ts/opsserver/classes.opsserver.d.ts +20 -0
  345. package/dist_ts/ts/opsserver/classes.opsserver.js +44 -0
  346. package/dist_ts/ts/opsserver/handlers/admin.handler.d.ts +31 -0
  347. package/dist_ts/ts/opsserver/handlers/admin.handler.js +177 -0
  348. package/dist_ts/ts/opsserver/handlers/config.handler.d.ts +10 -0
  349. package/dist_ts/ts/opsserver/handlers/config.handler.js +100 -0
  350. package/dist_ts/ts/opsserver/handlers/index.d.ts +5 -0
  351. package/dist_ts/ts/opsserver/handlers/index.js +6 -0
  352. package/dist_ts/ts/opsserver/handlers/logs.handler.d.ts +10 -0
  353. package/dist_ts/ts/opsserver/handlers/logs.handler.js +121 -0
  354. package/dist_ts/ts/opsserver/handlers/security.handler.d.ts +11 -0
  355. package/dist_ts/ts/opsserver/handlers/security.handler.js +118 -0
  356. package/dist_ts/ts/opsserver/handlers/stats.handler.d.ts +13 -0
  357. package/dist_ts/ts/opsserver/handlers/stats.handler.js +233 -0
  358. package/dist_ts/ts/opsserver/helpers/guards.d.ts +25 -0
  359. package/dist_ts/ts/opsserver/helpers/guards.js +41 -0
  360. package/dist_ts/ts/opsserver/index.d.ts +1 -0
  361. package/dist_ts/ts/opsserver/index.js +2 -0
  362. package/dist_ts/ts/paths.d.ts +14 -0
  363. package/dist_ts/ts/paths.js +39 -0
  364. package/dist_ts/ts/plugins.d.ts +46 -0
  365. package/dist_ts/ts/plugins.js +53 -0
  366. package/dist_ts/ts/security/classes.contentscanner.d.ts +160 -0
  367. package/dist_ts/ts/security/classes.contentscanner.js +634 -0
  368. package/dist_ts/ts/security/classes.ipreputationchecker.d.ts +150 -0
  369. package/dist_ts/ts/security/classes.ipreputationchecker.js +508 -0
  370. package/dist_ts/ts/security/classes.securitylogger.d.ts +140 -0
  371. package/dist_ts/ts/security/classes.securitylogger.js +232 -0
  372. package/dist_ts/ts/security/index.d.ts +3 -0
  373. package/dist_ts/ts/security/index.js +4 -0
  374. package/dist_ts/ts/sms/classes.smsservice.d.ts +15 -0
  375. package/dist_ts/ts/sms/classes.smsservice.js +72 -0
  376. package/dist_ts/ts/sms/config/sms.config.d.ts +93 -0
  377. package/dist_ts/ts/sms/config/sms.config.js +2 -0
  378. package/dist_ts/ts/sms/config/sms.schema.d.ts +5 -0
  379. package/dist_ts/ts/sms/config/sms.schema.js +121 -0
  380. package/dist_ts/ts/sms/index.d.ts +1 -0
  381. package/dist_ts/ts/sms/index.js +2 -0
  382. package/dist_ts/ts/storage/classes.storagemanager.d.ts +82 -0
  383. package/dist_ts/ts/storage/classes.storagemanager.js +341 -0
  384. package/dist_ts/ts/storage/index.d.ts +1 -0
  385. package/dist_ts/ts/storage/index.js +3 -0
  386. package/dist_ts/ts_interfaces/data/auth.d.ts +8 -0
  387. package/dist_ts/ts_interfaces/data/auth.js +2 -0
  388. package/dist_ts/ts_interfaces/data/index.d.ts +2 -0
  389. package/dist_ts/ts_interfaces/data/index.js +3 -0
  390. package/dist_ts/ts_interfaces/data/stats.d.ts +93 -0
  391. package/dist_ts/ts_interfaces/data/stats.js +2 -0
  392. package/dist_ts/ts_interfaces/index.d.ts +5 -0
  393. package/dist_ts/ts_interfaces/index.js +8 -0
  394. package/dist_ts/ts_interfaces/plugins.d.ts +2 -0
  395. package/dist_ts/ts_interfaces/plugins.js +4 -0
  396. package/dist_ts/ts_interfaces/requests/admin.d.ts +31 -0
  397. package/dist_ts/ts_interfaces/requests/admin.js +3 -0
  398. package/dist_ts/ts_interfaces/requests/config.d.ts +25 -0
  399. package/dist_ts/ts_interfaces/requests/config.js +3 -0
  400. package/dist_ts/ts_interfaces/requests/index.d.ts +4 -0
  401. package/dist_ts/ts_interfaces/requests/index.js +5 -0
  402. package/dist_ts/ts_interfaces/requests/logs.d.ts +34 -0
  403. package/dist_ts/ts_interfaces/requests/logs.js +4 -0
  404. package/dist_ts/ts_interfaces/requests/stats.d.ts +131 -0
  405. package/dist_ts/ts_interfaces/requests/stats.js +4 -0
  406. package/html/index.html +121 -0
  407. package/npmextra.json +45 -0
  408. package/package.json +83 -0
  409. package/readme.hints.md +906 -0
  410. package/readme.md +1253 -0
  411. package/readme.opsserver.md +351 -0
  412. package/test/helpers/server.loader.ts +347 -0
  413. package/test/helpers/smtp.client.ts +209 -0
  414. package/test/helpers/utils.ts +311 -0
  415. package/test/readme.md +443 -0
  416. package/test/suite/smtpclient_commands/test.ccmd-01.ehlo-helo-sending.ts +168 -0
  417. package/test/suite/smtpclient_commands/test.ccmd-02.mail-from-parameters.ts +277 -0
  418. package/test/suite/smtpclient_commands/test.ccmd-03.rcpt-to-multiple.ts +283 -0
  419. package/test/suite/smtpclient_commands/test.ccmd-04.data-transmission.ts +274 -0
  420. package/test/suite/smtpclient_commands/test.ccmd-05.auth-mechanisms.ts +306 -0
  421. package/test/suite/smtpclient_commands/test.ccmd-06.command-pipelining.ts +233 -0
  422. package/test/suite/smtpclient_commands/test.ccmd-07.response-parsing.ts +243 -0
  423. package/test/suite/smtpclient_commands/test.ccmd-08.rset-command.ts +333 -0
  424. package/test/suite/smtpclient_commands/test.ccmd-09.noop-command.ts +339 -0
  425. package/test/suite/smtpclient_commands/test.ccmd-10.vrfy-expn.ts +457 -0
  426. package/test/suite/smtpclient_commands/test.ccmd-11.help-command.ts +409 -0
  427. package/test/suite/smtpclient_connection/test.ccm-01.basic-tcp-connection.ts +150 -0
  428. package/test/suite/smtpclient_connection/test.ccm-02.tls-connection.ts +140 -0
  429. package/test/suite/smtpclient_connection/test.ccm-03.starttls-upgrade.ts +208 -0
  430. package/test/suite/smtpclient_connection/test.ccm-04.connection-pooling.ts +250 -0
  431. package/test/suite/smtpclient_connection/test.ccm-05.connection-reuse.ts +288 -0
  432. package/test/suite/smtpclient_connection/test.ccm-06.connection-timeout.ts +267 -0
  433. package/test/suite/smtpclient_connection/test.ccm-07.automatic-reconnection.ts +324 -0
  434. package/test/suite/smtpclient_connection/test.ccm-08.dns-resolution.ts +139 -0
  435. package/test/suite/smtpclient_connection/test.ccm-09.ipv6-dual-stack.ts +167 -0
  436. package/test/suite/smtpclient_connection/test.ccm-10.proxy-support.ts +305 -0
  437. package/test/suite/smtpclient_connection/test.ccm-11.keepalive.ts +299 -0
  438. package/test/suite/smtpclient_edge-cases/test.cedge-01.unusual-server-responses.ts +529 -0
  439. package/test/suite/smtpclient_edge-cases/test.cedge-02.malformed-commands.ts +438 -0
  440. package/test/suite/smtpclient_edge-cases/test.cedge-03.protocol-violations.ts +446 -0
  441. package/test/suite/smtpclient_edge-cases/test.cedge-04.resource-constraints.ts +530 -0
  442. package/test/suite/smtpclient_edge-cases/test.cedge-05.encoding-issues.ts +145 -0
  443. package/test/suite/smtpclient_edge-cases/test.cedge-06.large-headers.ts +180 -0
  444. package/test/suite/smtpclient_edge-cases/test.cedge-07.concurrent-operations.ts +204 -0
  445. package/test/suite/smtpclient_email-composition/test.cep-01.basic-headers.ts +245 -0
  446. package/test/suite/smtpclient_email-composition/test.cep-02.mime-multipart.ts +321 -0
  447. package/test/suite/smtpclient_email-composition/test.cep-03.attachment-encoding.ts +334 -0
  448. package/test/suite/smtpclient_email-composition/test.cep-04.bcc-handling.ts +187 -0
  449. package/test/suite/smtpclient_email-composition/test.cep-05.reply-to-return-path.ts +277 -0
  450. package/test/suite/smtpclient_email-composition/test.cep-06.utf8-international.ts +235 -0
  451. package/test/suite/smtpclient_email-composition/test.cep-07.html-inline-images.ts +489 -0
  452. package/test/suite/smtpclient_email-composition/test.cep-08.custom-headers.ts +293 -0
  453. package/test/suite/smtpclient_email-composition/test.cep-09.priority-importance.ts +314 -0
  454. package/test/suite/smtpclient_email-composition/test.cep-10.receipts-dsn.ts +411 -0
  455. package/test/suite/smtpclient_error-handling/test.cerr-01.4xx-errors.ts +232 -0
  456. package/test/suite/smtpclient_error-handling/test.cerr-02.5xx-errors.ts +309 -0
  457. package/test/suite/smtpclient_error-handling/test.cerr-03.network-failures.ts +299 -0
  458. package/test/suite/smtpclient_error-handling/test.cerr-04.greylisting-handling.ts +255 -0
  459. package/test/suite/smtpclient_error-handling/test.cerr-05.quota-exceeded.ts +273 -0
  460. package/test/suite/smtpclient_error-handling/test.cerr-06.invalid-recipients.ts +320 -0
  461. package/test/suite/smtpclient_error-handling/test.cerr-07.message-size-limits.ts +320 -0
  462. package/test/suite/smtpclient_error-handling/test.cerr-08.rate-limiting.ts +261 -0
  463. package/test/suite/smtpclient_error-handling/test.cerr-09.connection-pool-errors.ts +299 -0
  464. package/test/suite/smtpclient_error-handling/test.cerr-10.partial-failure.ts +373 -0
  465. package/test/suite/smtpclient_performance/test.cperf-01.bulk-sending.ts +332 -0
  466. package/test/suite/smtpclient_performance/test.cperf-02.message-throughput.ts +304 -0
  467. package/test/suite/smtpclient_performance/test.cperf-03.memory-usage.ts +332 -0
  468. package/test/suite/smtpclient_performance/test.cperf-04.cpu-utilization.ts +373 -0
  469. package/test/suite/smtpclient_performance/test.cperf-05.network-efficiency.ts +181 -0
  470. package/test/suite/smtpclient_performance/test.cperf-06.caching-strategies.ts +190 -0
  471. package/test/suite/smtpclient_performance/test.cperf-07.queue-management.ts +171 -0
  472. package/test/suite/smtpclient_performance/test.cperf-08.dns-caching.ts +50 -0
  473. package/test/suite/smtpclient_reliability/test.crel-01.reconnection-logic.ts +305 -0
  474. package/test/suite/smtpclient_reliability/test.crel-02.network-interruption.ts +207 -0
  475. package/test/suite/smtpclient_reliability/test.crel-03.queue-persistence.ts +469 -0
  476. package/test/suite/smtpclient_reliability/test.crel-04.crash-recovery.ts +520 -0
  477. package/test/suite/smtpclient_reliability/test.crel-05.memory-leaks.ts +503 -0
  478. package/test/suite/smtpclient_reliability/test.crel-06.concurrency-safety.ts +558 -0
  479. package/test/suite/smtpclient_reliability/test.crel-07.resource-cleanup.ts +52 -0
  480. package/test/suite/smtpclient_rfc-compliance/test.crfc-01.rfc5321-client.ts +283 -0
  481. package/test/suite/smtpclient_rfc-compliance/test.crfc-02.esmtp-compliance.ts +77 -0
  482. package/test/suite/smtpclient_rfc-compliance/test.crfc-03.command-syntax.ts +67 -0
  483. package/test/suite/smtpclient_rfc-compliance/test.crfc-04.response-codes.ts +54 -0
  484. package/test/suite/smtpclient_rfc-compliance/test.crfc-05.state-machine.ts +703 -0
  485. package/test/suite/smtpclient_rfc-compliance/test.crfc-06.protocol-negotiation.ts +688 -0
  486. package/test/suite/smtpclient_rfc-compliance/test.crfc-07.interoperability.ts +728 -0
  487. package/test/suite/smtpclient_rfc-compliance/test.crfc-08.smtp-extensions.ts +656 -0
  488. package/test/suite/smtpclient_security/test.csec-01.tls-verification.ts +88 -0
  489. package/test/suite/smtpclient_security/test.csec-02.oauth2-authentication.ts +132 -0
  490. package/test/suite/smtpclient_security/test.csec-03.dkim-signing.ts +138 -0
  491. package/test/suite/smtpclient_security/test.csec-04.spf-compliance.ts +163 -0
  492. package/test/suite/smtpclient_security/test.csec-05.dmarc-policy.ts +200 -0
  493. package/test/suite/smtpclient_security/test.csec-06.certificate-validation.ts +145 -0
  494. package/test/suite/smtpclient_security/test.csec-07.cipher-suites.ts +153 -0
  495. package/test/suite/smtpclient_security/test.csec-08.authentication-fallback.ts +154 -0
  496. package/test/suite/smtpclient_security/test.csec-09.relay-restrictions.ts +166 -0
  497. package/test/suite/smtpclient_security/test.csec-10.anti-spam-measures.ts +196 -0
  498. package/test/suite/smtpserver_commands/test.cmd-01.ehlo-command.ts +193 -0
  499. package/test/suite/smtpserver_commands/test.cmd-02.mail-from.ts +330 -0
  500. package/test/suite/smtpserver_commands/test.cmd-03.rcpt-to.ts +296 -0
  501. package/test/suite/smtpserver_commands/test.cmd-04.data-command.ts +395 -0
  502. package/test/suite/smtpserver_commands/test.cmd-05.noop-command.ts +320 -0
  503. package/test/suite/smtpserver_commands/test.cmd-06.rset-command.ts +399 -0
  504. package/test/suite/smtpserver_commands/test.cmd-07.vrfy-command.ts +391 -0
  505. package/test/suite/smtpserver_commands/test.cmd-08.expn-command.ts +450 -0
  506. package/test/suite/smtpserver_commands/test.cmd-09.size-extension.ts +465 -0
  507. package/test/suite/smtpserver_commands/test.cmd-10.help-command.ts +454 -0
  508. package/test/suite/smtpserver_commands/test.cmd-11.command-pipelining.ts +334 -0
  509. package/test/suite/smtpserver_commands/test.cmd-12.helo-command.ts +420 -0
  510. package/test/suite/smtpserver_commands/test.cmd-13.quit-command.ts +384 -0
  511. package/test/suite/smtpserver_connection/test.cm-01.tls-connection.ts +61 -0
  512. package/test/suite/smtpserver_connection/test.cm-02.multiple-connections.ts +112 -0
  513. package/test/suite/smtpserver_connection/test.cm-03.connection-timeout.ts +134 -0
  514. package/test/suite/smtpserver_connection/test.cm-04.connection-limits.ts +374 -0
  515. package/test/suite/smtpserver_connection/test.cm-05.connection-rejection.ts +296 -0
  516. package/test/suite/smtpserver_connection/test.cm-06.starttls-upgrade.ts +468 -0
  517. package/test/suite/smtpserver_connection/test.cm-07.abrupt-disconnection.ts +321 -0
  518. package/test/suite/smtpserver_connection/test.cm-08.tls-versions.ts +361 -0
  519. package/test/suite/smtpserver_connection/test.cm-09.tls-ciphers.ts +556 -0
  520. package/test/suite/smtpserver_connection/test.cm-10.plain-connection.ts +293 -0
  521. package/test/suite/smtpserver_connection/test.cm-11.keepalive.ts +382 -0
  522. package/test/suite/smtpserver_edge-cases/test.edge-01.very-large-email.ts +239 -0
  523. package/test/suite/smtpserver_edge-cases/test.edge-02.very-small-email.ts +389 -0
  524. package/test/suite/smtpserver_edge-cases/test.edge-03.invalid-character-handling.ts +479 -0
  525. package/test/suite/smtpserver_edge-cases/test.edge-04.empty-commands.ts +430 -0
  526. package/test/suite/smtpserver_edge-cases/test.edge-05.extremely-long-lines.ts +425 -0
  527. package/test/suite/smtpserver_edge-cases/test.edge-06.extremely-long-headers.ts +404 -0
  528. package/test/suite/smtpserver_edge-cases/test.edge-07.unusual-mime-types.ts +333 -0
  529. package/test/suite/smtpserver_edge-cases/test.edge-08.nested-mime-structures.ts +379 -0
  530. package/test/suite/smtpserver_email-processing/test.ep-01.basic-email-sending.ts +338 -0
  531. package/test/suite/smtpserver_email-processing/test.ep-02.invalid-email-addresses.ts +315 -0
  532. package/test/suite/smtpserver_email-processing/test.ep-03.multiple-recipients.ts +493 -0
  533. package/test/suite/smtpserver_email-processing/test.ep-04.large-email.ts +528 -0
  534. package/test/suite/smtpserver_email-processing/test.ep-05.mime-handling.ts +515 -0
  535. package/test/suite/smtpserver_email-processing/test.ep-06.attachment-handling.ts +629 -0
  536. package/test/suite/smtpserver_email-processing/test.ep-07.special-character-handling.ts +462 -0
  537. package/test/suite/smtpserver_email-processing/test.ep-08.email-routing.ts +527 -0
  538. package/test/suite/smtpserver_email-processing/test.ep-09.delivery-status-notifications.ts +486 -0
  539. package/test/suite/smtpserver_error-handling/test.err-01.syntax-errors.ts +475 -0
  540. package/test/suite/smtpserver_error-handling/test.err-02.invalid-sequence.ts +450 -0
  541. package/test/suite/smtpserver_error-handling/test.err-03.temporary-failures.ts +453 -0
  542. package/test/suite/smtpserver_error-handling/test.err-04.permanent-failures.ts +325 -0
  543. package/test/suite/smtpserver_error-handling/test.err-05.resource-exhaustion.ts +302 -0
  544. package/test/suite/smtpserver_error-handling/test.err-06.malformed-mime.ts +374 -0
  545. package/test/suite/smtpserver_error-handling/test.err-07.exception-handling.ts +333 -0
  546. package/test/suite/smtpserver_error-handling/test.err-08.error-logging.ts +324 -0
  547. package/test/suite/smtpserver_performance/test.perf-01.throughput.ts +183 -0
  548. package/test/suite/smtpserver_performance/test.perf-02.concurrency.ts +388 -0
  549. package/test/suite/smtpserver_performance/test.perf-03.cpu-utilization.ts +245 -0
  550. package/test/suite/smtpserver_performance/test.perf-04.memory-usage.ts +238 -0
  551. package/test/suite/smtpserver_performance/test.perf-05.connection-processing-time.ts +363 -0
  552. package/test/suite/smtpserver_performance/test.perf-06.message-processing-time.ts +252 -0
  553. package/test/suite/smtpserver_performance/test.perf-07.resource-cleanup.ts +317 -0
  554. package/test/suite/smtpserver_reliability/test.rel-01.long-running-operation.ts +344 -0
  555. package/test/suite/smtpserver_reliability/test.rel-02.restart-recovery.ts +328 -0
  556. package/test/suite/smtpserver_reliability/test.rel-03.resource-leak-detection.ts +394 -0
  557. package/test/suite/smtpserver_reliability/test.rel-04.error-recovery.ts +401 -0
  558. package/test/suite/smtpserver_reliability/test.rel-05.dns-resolution-failure.ts +335 -0
  559. package/test/suite/smtpserver_reliability/test.rel-06.network-interruption.ts +410 -0
  560. package/test/suite/smtpserver_rfc-compliance/test.rfc-01.rfc5321-compliance.ts +382 -0
  561. package/test/suite/smtpserver_rfc-compliance/test.rfc-02.rfc5322-compliance.ts +428 -0
  562. package/test/suite/smtpserver_rfc-compliance/test.rfc-03.rfc7208-spf-compliance.ts +330 -0
  563. package/test/suite/smtpserver_rfc-compliance/test.rfc-04.rfc6376-dkim-compliance.ts +450 -0
  564. package/test/suite/smtpserver_rfc-compliance/test.rfc-05.rfc7489-dmarc-compliance.ts +408 -0
  565. package/test/suite/smtpserver_rfc-compliance/test.rfc-06.rfc8314-tls-compliance.ts +366 -0
  566. package/test/suite/smtpserver_rfc-compliance/test.rfc-07.rfc3461-dsn-compliance.ts +399 -0
  567. package/test/suite/smtpserver_security/test.sec-01.authentication.ts +218 -0
  568. package/test/suite/smtpserver_security/test.sec-02.authorization.ts +286 -0
  569. package/test/suite/smtpserver_security/test.sec-03.dkim-processing.ts +414 -0
  570. package/test/suite/smtpserver_security/test.sec-04.spf-checking.ts +280 -0
  571. package/test/suite/smtpserver_security/test.sec-05.dmarc-policy.ts +374 -0
  572. package/test/suite/smtpserver_security/test.sec-06.ip-reputation.ts +303 -0
  573. package/test/suite/smtpserver_security/test.sec-07.content-scanning.ts +409 -0
  574. package/test/suite/smtpserver_security/test.sec-08.rate-limiting.ts +324 -0
  575. package/test/suite/smtpserver_security/test.sec-09.tls-certificate-validation.ts +312 -0
  576. package/test/suite/smtpserver_security/test.sec-10.header-injection-prevention.ts +332 -0
  577. package/test/suite/smtpserver_security/test.sec-11.bounce-management.ts +363 -0
  578. package/test/test.base.ts +65 -0
  579. package/test/test.bouncemanager.ts +196 -0
  580. package/test/test.config.md +175 -0
  581. package/test/test.contentscanner.ts +265 -0
  582. package/test/test.dcrouter.email.ts +201 -0
  583. package/test/test.deliverability.ts +55 -0
  584. package/test/test.dns-manager-creation.ts +141 -0
  585. package/test/test.dns-mode-switching.ts +257 -0
  586. package/test/test.dns-server-config.ts +140 -0
  587. package/test/test.dns-socket-handler.ts +169 -0
  588. package/test/test.dns-validation.ts +283 -0
  589. package/test/test.email-socket-handler.ts +228 -0
  590. package/test/test.email.integration.ts +377 -0
  591. package/test/test.email.router.ts +283 -0
  592. package/test/test.emailauth.ts +195 -0
  593. package/test/test.errors.ts +408 -0
  594. package/test/test.integration.storage.ts +313 -0
  595. package/test/test.integration.ts +75 -0
  596. package/test/test.ipreputationchecker.ts +179 -0
  597. package/test/test.ipwarmupmanager.ts +323 -0
  598. package/test/test.jwt-auth.ts +130 -0
  599. package/test/test.minimal.ts +66 -0
  600. package/test/test.opsserver-api.ts +83 -0
  601. package/test/test.protected-endpoint.ts +115 -0
  602. package/test/test.rate-limiting-integration.ts +236 -0
  603. package/test/test.ratelimiter.ts +141 -0
  604. package/test/test.reputationmonitor.ts +262 -0
  605. package/test/test.smartmail.ts +248 -0
  606. package/test/test.smtp.client.compatibility.ts +154 -0
  607. package/test/test.smtp.client.ts +191 -0
  608. package/test/test.smtp.server.ts +180 -0
  609. package/test/test.socket-handler-integration.ts +240 -0
  610. package/test/test.socket-handler-unit.ts +198 -0
  611. package/test/test.storagemanager.ts +289 -0
  612. package/ts/00_commitinfo_data.ts +8 -0
  613. package/ts/classes.dcrouter.ts +1310 -0
  614. package/ts/config/index.ts +2 -0
  615. package/ts/config/validator.ts +266 -0
  616. package/ts/deliverability/classes.ipwarmupmanager.ts +896 -0
  617. package/ts/deliverability/classes.senderreputationmonitor.ts +1244 -0
  618. package/ts/deliverability/index.ts +13 -0
  619. package/ts/errors/base.errors.ts +525 -0
  620. package/ts/errors/email.errors.ts +383 -0
  621. package/ts/errors/error-handler.ts +412 -0
  622. package/ts/errors/error.codes.ts +165 -0
  623. package/ts/errors/index.ts +195 -0
  624. package/ts/errors/mta.errors.ts +681 -0
  625. package/ts/errors/reputation.errors.ts +422 -0
  626. package/ts/index.ts +7 -0
  627. package/ts/logger.ts +91 -0
  628. package/ts/mail/core/classes.bouncemanager.ts +965 -0
  629. package/ts/mail/core/classes.email.ts +941 -0
  630. package/ts/mail/core/classes.emailvalidator.ts +239 -0
  631. package/ts/mail/core/classes.templatemanager.ts +320 -0
  632. package/ts/mail/core/index.ts +5 -0
  633. package/ts/mail/delivery/classes.delivery.queue.ts +645 -0
  634. package/ts/mail/delivery/classes.delivery.system.ts +1089 -0
  635. package/ts/mail/delivery/classes.emailsendjob.ts +447 -0
  636. package/ts/mail/delivery/classes.emailsendjob.ts.backup +691 -0
  637. package/ts/mail/delivery/classes.emailsignjob.ts +67 -0
  638. package/ts/mail/delivery/classes.mta.config.ts +73 -0
  639. package/ts/mail/delivery/classes.ratelimiter.ts +281 -0
  640. package/ts/mail/delivery/classes.smtp.client.legacy.ts +1422 -0
  641. package/ts/mail/delivery/classes.unified.rate.limiter.ts +1053 -0
  642. package/ts/mail/delivery/index.ts +24 -0
  643. package/ts/mail/delivery/interfaces.ts +291 -0
  644. package/ts/mail/delivery/smtpclient/auth-handler.ts +232 -0
  645. package/ts/mail/delivery/smtpclient/command-handler.ts +343 -0
  646. package/ts/mail/delivery/smtpclient/connection-manager.ts +289 -0
  647. package/ts/mail/delivery/smtpclient/constants.ts +145 -0
  648. package/ts/mail/delivery/smtpclient/create-client.ts +94 -0
  649. package/ts/mail/delivery/smtpclient/error-handler.ts +141 -0
  650. package/ts/mail/delivery/smtpclient/index.ts +24 -0
  651. package/ts/mail/delivery/smtpclient/interfaces.ts +242 -0
  652. package/ts/mail/delivery/smtpclient/smtp-client.ts +357 -0
  653. package/ts/mail/delivery/smtpclient/tls-handler.ts +254 -0
  654. package/ts/mail/delivery/smtpclient/utils/helpers.ts +224 -0
  655. package/ts/mail/delivery/smtpclient/utils/logging.ts +212 -0
  656. package/ts/mail/delivery/smtpclient/utils/validation.ts +170 -0
  657. package/ts/mail/delivery/smtpserver/certificate-utils.ts +398 -0
  658. package/ts/mail/delivery/smtpserver/command-handler.ts +1340 -0
  659. package/ts/mail/delivery/smtpserver/connection-manager.ts +1045 -0
  660. package/ts/mail/delivery/smtpserver/constants.ts +181 -0
  661. package/ts/mail/delivery/smtpserver/create-server.ts +31 -0
  662. package/ts/mail/delivery/smtpserver/data-handler.ts +1283 -0
  663. package/ts/mail/delivery/smtpserver/index.ts +32 -0
  664. package/ts/mail/delivery/smtpserver/interfaces.ts +655 -0
  665. package/ts/mail/delivery/smtpserver/secure-server.ts +97 -0
  666. package/ts/mail/delivery/smtpserver/security-handler.ts +345 -0
  667. package/ts/mail/delivery/smtpserver/session-manager.ts +557 -0
  668. package/ts/mail/delivery/smtpserver/smtp-server.ts +804 -0
  669. package/ts/mail/delivery/smtpserver/starttls-handler.ts +262 -0
  670. package/ts/mail/delivery/smtpserver/tls-handler.ts +346 -0
  671. package/ts/mail/delivery/smtpserver/utils/adaptive-logging.ts +514 -0
  672. package/ts/mail/delivery/smtpserver/utils/helpers.ts +246 -0
  673. package/ts/mail/delivery/smtpserver/utils/logging.ts +246 -0
  674. package/ts/mail/delivery/smtpserver/utils/validation.ts +436 -0
  675. package/ts/mail/index.ts +19 -0
  676. package/ts/mail/routing/classes.dns.manager.ts +563 -0
  677. package/ts/mail/routing/classes.dnsmanager.ts +559 -0
  678. package/ts/mail/routing/classes.domain.registry.ts +139 -0
  679. package/ts/mail/routing/classes.email.config.ts +82 -0
  680. package/ts/mail/routing/classes.email.router.ts +575 -0
  681. package/ts/mail/routing/classes.unified.email.server.ts +1873 -0
  682. package/ts/mail/routing/index.ts +6 -0
  683. package/ts/mail/routing/interfaces.ts +202 -0
  684. package/ts/mail/security/classes.dkimcreator.ts +431 -0
  685. package/ts/mail/security/classes.dkimverifier.ts +382 -0
  686. package/ts/mail/security/classes.dmarcverifier.ts +478 -0
  687. package/ts/mail/security/classes.spfverifier.ts +606 -0
  688. package/ts/mail/security/index.ts +5 -0
  689. package/ts/opsserver/classes.opsserver.ts +65 -0
  690. package/ts/opsserver/handlers/admin.handler.ts +240 -0
  691. package/ts/opsserver/handlers/config.handler.ts +150 -0
  692. package/ts/opsserver/handlers/index.ts +5 -0
  693. package/ts/opsserver/handlers/logs.handler.ts +195 -0
  694. package/ts/opsserver/handlers/security.handler.ts +208 -0
  695. package/ts/opsserver/handlers/stats.handler.ts +344 -0
  696. package/ts/opsserver/helpers/guards.ts +56 -0
  697. package/ts/opsserver/index.ts +1 -0
  698. package/ts/paths.ts +48 -0
  699. package/ts/plugins.ts +94 -0
  700. package/ts/security/classes.contentscanner.ts +739 -0
  701. package/ts/security/classes.ipreputationchecker.ts +592 -0
  702. package/ts/security/classes.securitylogger.ts +299 -0
  703. package/ts/security/index.ts +21 -0
  704. package/ts/sms/classes.smsservice.ts +98 -0
  705. package/ts/sms/config/sms.config.ts +109 -0
  706. package/ts/sms/config/sms.schema.ts +122 -0
  707. package/ts/sms/index.ts +1 -0
  708. package/ts/storage/classes.storagemanager.ts +400 -0
  709. package/ts/storage/index.ts +2 -0
  710. package/ts/tspublish.json +3 -0
  711. package/ts_interfaces/data/auth.ts +8 -0
  712. package/ts_interfaces/data/index.ts +2 -0
  713. package/ts_interfaces/data/stats.ts +101 -0
  714. package/ts_interfaces/index.ts +9 -0
  715. package/ts_interfaces/plugins.ts +6 -0
  716. package/ts_interfaces/requests/admin.ts +46 -0
  717. package/ts_interfaces/requests/config.ts +35 -0
  718. package/ts_interfaces/requests/index.ts +4 -0
  719. package/ts_interfaces/requests/logs.ts +44 -0
  720. package/ts_interfaces/requests/stats.ts +162 -0
  721. package/ts_interfaces/tspublish.json +3 -0
  722. package/ts_web/00_commitinfo_data.ts +8 -0
  723. package/ts_web/appstate.ts +361 -0
  724. package/ts_web/elements/index.ts +7 -0
  725. package/ts_web/elements/ops-dashboard.ts +165 -0
  726. package/ts_web/elements/ops-view-config.ts +268 -0
  727. package/ts_web/elements/ops-view-logs.ts +207 -0
  728. package/ts_web/elements/ops-view-overview.ts +222 -0
  729. package/ts_web/elements/ops-view-security.ts +471 -0
  730. package/ts_web/elements/ops-view-stats.ts +299 -0
  731. package/ts_web/elements/shared/css.ts +10 -0
  732. package/ts_web/elements/shared/index.ts +2 -0
  733. package/ts_web/elements/shared/ops-sectionheading.ts +42 -0
  734. package/ts_web/index.ts +9 -0
  735. package/ts_web/plugins.ts +11 -0
  736. package/ts_web/tspublish.json +3 -0
  737. package/tsconfig.json +15 -0
@@ -0,0 +1,894 @@
1
+ /**
2
+ * SMTP Connection Manager
3
+ * Responsible for managing socket connections to the SMTP server
4
+ */
5
+ import * as plugins from '../../../plugins.js';
6
+ import { SmtpResponseCode, SMTP_DEFAULTS, SmtpState } from './constants.js';
7
+ import { SmtpLogger } from './utils/logging.js';
8
+ import { adaptiveLogger } from './utils/adaptive-logging.js';
9
+ import { getSocketDetails, formatMultilineResponse } from './utils/helpers.js';
10
+ /**
11
+ * Manager for SMTP connections
12
+ * Handles connection setup, event listeners, and lifecycle management
13
+ * Provides resource management, connection tracking, and monitoring
14
+ */
15
+ export class ConnectionManager {
16
+ /**
17
+ * Creates a new connection manager with enhanced resource management
18
+ * @param smtpServer - SMTP server instance
19
+ */
20
+ constructor(smtpServer) {
21
+ /**
22
+ * Set of active socket connections
23
+ */
24
+ this.activeConnections = new Set();
25
+ /**
26
+ * Connection tracking for resource management
27
+ */
28
+ this.connectionStats = {
29
+ totalConnections: 0,
30
+ activeConnections: 0,
31
+ peakConnections: 0,
32
+ rejectedConnections: 0,
33
+ closedConnections: 0,
34
+ erroredConnections: 0,
35
+ timedOutConnections: 0
36
+ };
37
+ /**
38
+ * Per-IP connection tracking for rate limiting
39
+ */
40
+ this.ipConnections = new Map();
41
+ /**
42
+ * Resource monitoring interval
43
+ */
44
+ this.resourceCheckInterval = null;
45
+ /**
46
+ * Track cleanup timers so we can clear them
47
+ */
48
+ this.cleanupTimers = new Set();
49
+ this.smtpServer = smtpServer;
50
+ // Get options from server
51
+ const serverOptions = this.smtpServer.getOptions();
52
+ // Default values for resource management - adjusted for production scalability
53
+ const DEFAULT_MAX_CONNECTIONS_PER_IP = 50; // Increased to support high-concurrency scenarios
54
+ const DEFAULT_CONNECTION_RATE_LIMIT = 200; // Increased for production load handling
55
+ const DEFAULT_CONNECTION_RATE_WINDOW = 60 * 1000; // 60 seconds window
56
+ const DEFAULT_BUFFER_SIZE_LIMIT = 10 * 1024 * 1024; // 10 MB
57
+ const DEFAULT_RESOURCE_CHECK_INTERVAL = 30 * 1000; // 30 seconds
58
+ this.options = {
59
+ hostname: serverOptions.hostname || SMTP_DEFAULTS.HOSTNAME,
60
+ maxConnections: serverOptions.maxConnections || SMTP_DEFAULTS.MAX_CONNECTIONS,
61
+ socketTimeout: serverOptions.socketTimeout || SMTP_DEFAULTS.SOCKET_TIMEOUT,
62
+ maxConnectionsPerIP: DEFAULT_MAX_CONNECTIONS_PER_IP,
63
+ connectionRateLimit: DEFAULT_CONNECTION_RATE_LIMIT,
64
+ connectionRateWindow: DEFAULT_CONNECTION_RATE_WINDOW,
65
+ bufferSizeLimit: DEFAULT_BUFFER_SIZE_LIMIT,
66
+ resourceCheckInterval: DEFAULT_RESOURCE_CHECK_INTERVAL
67
+ };
68
+ // Start resource monitoring
69
+ this.startResourceMonitoring();
70
+ }
71
+ /**
72
+ * Start resource monitoring interval to check resource usage
73
+ */
74
+ startResourceMonitoring() {
75
+ // Clear any existing interval
76
+ if (this.resourceCheckInterval) {
77
+ clearInterval(this.resourceCheckInterval);
78
+ }
79
+ // Set up new interval
80
+ this.resourceCheckInterval = setInterval(() => {
81
+ this.monitorResourceUsage();
82
+ }, this.options.resourceCheckInterval);
83
+ }
84
+ /**
85
+ * Monitor resource usage and log statistics
86
+ */
87
+ monitorResourceUsage() {
88
+ // Calculate memory usage
89
+ const memoryUsage = process.memoryUsage();
90
+ const memoryUsageMB = {
91
+ rss: Math.round(memoryUsage.rss / 1024 / 1024),
92
+ heapTotal: Math.round(memoryUsage.heapTotal / 1024 / 1024),
93
+ heapUsed: Math.round(memoryUsage.heapUsed / 1024 / 1024),
94
+ external: Math.round(memoryUsage.external / 1024 / 1024)
95
+ };
96
+ // Calculate connection rate metrics
97
+ const activeIPs = Array.from(this.ipConnections.entries())
98
+ .filter(([_, data]) => data.count > 0).length;
99
+ const highVolumeIPs = Array.from(this.ipConnections.entries())
100
+ .filter(([_, data]) => data.count > this.options.connectionRateLimit / 2).length;
101
+ // Log resource usage with more detailed metrics
102
+ SmtpLogger.info('Resource usage stats', {
103
+ connections: {
104
+ active: this.activeConnections.size,
105
+ total: this.connectionStats.totalConnections,
106
+ peak: this.connectionStats.peakConnections,
107
+ rejected: this.connectionStats.rejectedConnections,
108
+ closed: this.connectionStats.closedConnections,
109
+ errored: this.connectionStats.erroredConnections,
110
+ timedOut: this.connectionStats.timedOutConnections
111
+ },
112
+ memory: memoryUsageMB,
113
+ ipTracking: {
114
+ uniqueIPs: this.ipConnections.size,
115
+ activeIPs: activeIPs,
116
+ highVolumeIPs: highVolumeIPs
117
+ },
118
+ resourceLimits: {
119
+ maxConnections: this.options.maxConnections,
120
+ maxConnectionsPerIP: this.options.maxConnectionsPerIP,
121
+ connectionRateLimit: this.options.connectionRateLimit,
122
+ bufferSizeLimit: Math.round(this.options.bufferSizeLimit / 1024 / 1024) + 'MB'
123
+ }
124
+ });
125
+ // Check for potential DoS conditions
126
+ if (highVolumeIPs > 3) {
127
+ SmtpLogger.warn(`Potential DoS detected: ${highVolumeIPs} IPs with high connection rates`);
128
+ }
129
+ // Assess memory usage trends
130
+ if (memoryUsageMB.heapUsed > 500) { // Over 500MB heap used
131
+ SmtpLogger.warn(`High memory usage detected: ${memoryUsageMB.heapUsed}MB heap used`);
132
+ }
133
+ // Clean up expired IP rate limits and validate resource tracking
134
+ this.cleanupIpRateLimits();
135
+ }
136
+ /**
137
+ * Clean up expired IP rate limits and perform additional resource monitoring
138
+ */
139
+ cleanupIpRateLimits() {
140
+ const now = Date.now();
141
+ const windowThreshold = now - this.options.connectionRateWindow;
142
+ let activeIps = 0;
143
+ let removedEntries = 0;
144
+ // Iterate through IP connections and manage entries
145
+ for (const [ip, data] of this.ipConnections.entries()) {
146
+ // If the last connection was before the window threshold + one extra window, remove the entry
147
+ if (data.lastConnection < windowThreshold - this.options.connectionRateWindow) {
148
+ // Remove stale entries to prevent memory growth
149
+ this.ipConnections.delete(ip);
150
+ removedEntries++;
151
+ }
152
+ // If last connection was before the window threshold, reset the count
153
+ else if (data.lastConnection < windowThreshold) {
154
+ if (data.count > 0) {
155
+ // Reset but keep the IP in the map with a zero count
156
+ this.ipConnections.set(ip, {
157
+ count: 0,
158
+ firstConnection: now,
159
+ lastConnection: now
160
+ });
161
+ }
162
+ }
163
+ else {
164
+ // This IP is still active within the current window
165
+ activeIps++;
166
+ }
167
+ }
168
+ // Log cleanup activity if significant changes occurred
169
+ if (removedEntries > 0) {
170
+ SmtpLogger.debug(`IP rate limit cleanup: removed ${removedEntries} stale entries, ${this.ipConnections.size} remaining, ${activeIps} active in current window`);
171
+ }
172
+ // Check for memory leaks in connection tracking
173
+ if (this.activeConnections.size > 0 && this.connectionStats.activeConnections !== this.activeConnections.size) {
174
+ SmtpLogger.warn(`Connection tracking inconsistency detected: stats.active=${this.connectionStats.activeConnections}, actual=${this.activeConnections.size}`);
175
+ // Fix the inconsistency
176
+ this.connectionStats.activeConnections = this.activeConnections.size;
177
+ }
178
+ // Validate and clean leaked resources if needed
179
+ this.validateResourceTracking();
180
+ }
181
+ /**
182
+ * Validate and repair resource tracking to prevent leaks
183
+ */
184
+ validateResourceTracking() {
185
+ // Prepare a detailed report if inconsistencies are found
186
+ const inconsistenciesFound = [];
187
+ // 1. Check active connections count matches activeConnections set size
188
+ if (this.connectionStats.activeConnections !== this.activeConnections.size) {
189
+ inconsistenciesFound.push({
190
+ issue: 'Active connection count mismatch',
191
+ stats: this.connectionStats.activeConnections,
192
+ actual: this.activeConnections.size,
193
+ action: 'Auto-corrected'
194
+ });
195
+ this.connectionStats.activeConnections = this.activeConnections.size;
196
+ }
197
+ // 2. Check for destroyed sockets in active connections
198
+ let destroyedSocketsCount = 0;
199
+ for (const socket of this.activeConnections) {
200
+ if (socket.destroyed) {
201
+ destroyedSocketsCount++;
202
+ // This should not happen - remove destroyed sockets from tracking
203
+ this.activeConnections.delete(socket);
204
+ }
205
+ }
206
+ if (destroyedSocketsCount > 0) {
207
+ inconsistenciesFound.push({
208
+ issue: 'Destroyed sockets in active list',
209
+ count: destroyedSocketsCount,
210
+ action: 'Removed from tracking'
211
+ });
212
+ // Update active connections count after cleanup
213
+ this.connectionStats.activeConnections = this.activeConnections.size;
214
+ }
215
+ // 3. Check for sessions without corresponding active connections
216
+ const sessionCount = this.smtpServer.getSessionManager().getSessionCount();
217
+ if (sessionCount > this.activeConnections.size) {
218
+ inconsistenciesFound.push({
219
+ issue: 'Orphaned sessions',
220
+ sessions: sessionCount,
221
+ connections: this.activeConnections.size,
222
+ action: 'Session cleanup recommended'
223
+ });
224
+ }
225
+ // If any inconsistencies found, log a detailed report
226
+ if (inconsistenciesFound.length > 0) {
227
+ SmtpLogger.warn('Resource tracking inconsistencies detected and repaired', { inconsistencies: inconsistenciesFound });
228
+ }
229
+ }
230
+ /**
231
+ * Handle a new connection with resource management
232
+ * @param socket - Client socket
233
+ */
234
+ async handleNewConnection(socket) {
235
+ // Update connection stats
236
+ this.connectionStats.totalConnections++;
237
+ this.connectionStats.activeConnections = this.activeConnections.size + 1;
238
+ if (this.connectionStats.activeConnections > this.connectionStats.peakConnections) {
239
+ this.connectionStats.peakConnections = this.connectionStats.activeConnections;
240
+ }
241
+ // Get client IP
242
+ const remoteAddress = socket.remoteAddress || '0.0.0.0';
243
+ // Use UnifiedRateLimiter for connection rate limiting
244
+ const emailServer = this.smtpServer.getEmailServer();
245
+ const rateLimiter = emailServer.getRateLimiter();
246
+ // Check connection limit with UnifiedRateLimiter
247
+ const connectionResult = rateLimiter.recordConnection(remoteAddress);
248
+ if (!connectionResult.allowed) {
249
+ this.rejectConnection(socket, connectionResult.reason || 'Rate limit exceeded');
250
+ this.connectionStats.rejectedConnections++;
251
+ return;
252
+ }
253
+ // Still track IP connections locally for cleanup purposes
254
+ this.trackIPConnection(remoteAddress);
255
+ // Check if maximum global connections reached
256
+ if (this.hasReachedMaxConnections()) {
257
+ this.rejectConnection(socket, 'Too many connections');
258
+ this.connectionStats.rejectedConnections++;
259
+ return;
260
+ }
261
+ // Add socket to active connections
262
+ this.activeConnections.add(socket);
263
+ // Set up socket options
264
+ socket.setKeepAlive(true);
265
+ socket.setTimeout(this.options.socketTimeout);
266
+ // Explicitly set socket buffer sizes to prevent memory issues
267
+ socket.setNoDelay(true); // Disable Nagle's algorithm for better responsiveness
268
+ // Set limits on socket buffer size if supported by Node.js version
269
+ try {
270
+ // Here we set reasonable buffer limits to prevent memory exhaustion attacks
271
+ const highWaterMark = 64 * 1024; // 64 KB
272
+ // Note: Socket high water mark methods can't be set directly in newer Node.js versions
273
+ // These would need to be set during socket creation or with a different API
274
+ }
275
+ catch (error) {
276
+ // Ignore errors from older Node.js versions that don't support these methods
277
+ SmtpLogger.debug(`Could not set socket buffer limits: ${error instanceof Error ? error.message : String(error)}`);
278
+ }
279
+ // Track this IP connection
280
+ this.trackIPConnection(remoteAddress);
281
+ // Set up event handlers
282
+ this.setupSocketEventHandlers(socket);
283
+ // Create a session for this connection
284
+ this.smtpServer.getSessionManager().createSession(socket, false);
285
+ // Log the new connection using adaptive logger
286
+ const socketDetails = getSocketDetails(socket);
287
+ adaptiveLogger.logConnection(socket, 'connect');
288
+ // Update adaptive logger with current connection count
289
+ adaptiveLogger.updateConnectionCount(this.connectionStats.activeConnections);
290
+ // Send greeting
291
+ this.sendGreeting(socket);
292
+ }
293
+ /**
294
+ * Check if an IP has exceeded the rate limit
295
+ * @param ip - Client IP address
296
+ * @returns True if rate limited
297
+ */
298
+ isIPRateLimited(ip) {
299
+ const now = Date.now();
300
+ const ipData = this.ipConnections.get(ip);
301
+ if (!ipData) {
302
+ return false; // No previous connections
303
+ }
304
+ // Check if we're within the rate window
305
+ const isWithinWindow = now - ipData.firstConnection <= this.options.connectionRateWindow;
306
+ // If within window and count exceeds limit, rate limit is applied
307
+ if (isWithinWindow && ipData.count >= this.options.connectionRateLimit) {
308
+ SmtpLogger.warn(`Rate limit exceeded for IP ${ip}: ${ipData.count} connections in ${Math.round((now - ipData.firstConnection) / 1000)}s`);
309
+ return true;
310
+ }
311
+ return false;
312
+ }
313
+ /**
314
+ * Track a new connection from an IP
315
+ * @param ip - Client IP address
316
+ */
317
+ trackIPConnection(ip) {
318
+ const now = Date.now();
319
+ const ipData = this.ipConnections.get(ip);
320
+ if (!ipData) {
321
+ // First connection from this IP
322
+ this.ipConnections.set(ip, {
323
+ count: 1,
324
+ firstConnection: now,
325
+ lastConnection: now
326
+ });
327
+ }
328
+ else {
329
+ // Check if we need to reset the window
330
+ if (now - ipData.lastConnection > this.options.connectionRateWindow) {
331
+ // Reset the window
332
+ this.ipConnections.set(ip, {
333
+ count: 1,
334
+ firstConnection: now,
335
+ lastConnection: now
336
+ });
337
+ }
338
+ else {
339
+ // Increment within the current window
340
+ this.ipConnections.set(ip, {
341
+ count: ipData.count + 1,
342
+ firstConnection: ipData.firstConnection,
343
+ lastConnection: now
344
+ });
345
+ }
346
+ }
347
+ }
348
+ /**
349
+ * Check if an IP has reached its connection limit
350
+ * @param ip - Client IP address
351
+ * @returns True if limit reached
352
+ */
353
+ hasReachedIPConnectionLimit(ip) {
354
+ let ipConnectionCount = 0;
355
+ // Count active connections from this IP
356
+ for (const socket of this.activeConnections) {
357
+ if (socket.remoteAddress === ip) {
358
+ ipConnectionCount++;
359
+ }
360
+ }
361
+ return ipConnectionCount >= this.options.maxConnectionsPerIP;
362
+ }
363
+ /**
364
+ * Handle a new secure TLS connection with resource management
365
+ * @param socket - Client TLS socket
366
+ */
367
+ async handleNewSecureConnection(socket) {
368
+ // Update connection stats
369
+ this.connectionStats.totalConnections++;
370
+ this.connectionStats.activeConnections = this.activeConnections.size + 1;
371
+ if (this.connectionStats.activeConnections > this.connectionStats.peakConnections) {
372
+ this.connectionStats.peakConnections = this.connectionStats.activeConnections;
373
+ }
374
+ // Get client IP
375
+ const remoteAddress = socket.remoteAddress || '0.0.0.0';
376
+ // Use UnifiedRateLimiter for connection rate limiting
377
+ const emailServer = this.smtpServer.getEmailServer();
378
+ const rateLimiter = emailServer.getRateLimiter();
379
+ // Check connection limit with UnifiedRateLimiter
380
+ const connectionResult = rateLimiter.recordConnection(remoteAddress);
381
+ if (!connectionResult.allowed) {
382
+ this.rejectConnection(socket, connectionResult.reason || 'Rate limit exceeded');
383
+ this.connectionStats.rejectedConnections++;
384
+ return;
385
+ }
386
+ // Still track IP connections locally for cleanup purposes
387
+ this.trackIPConnection(remoteAddress);
388
+ // Check if maximum global connections reached
389
+ if (this.hasReachedMaxConnections()) {
390
+ this.rejectConnection(socket, 'Too many connections');
391
+ this.connectionStats.rejectedConnections++;
392
+ return;
393
+ }
394
+ // Add socket to active connections
395
+ this.activeConnections.add(socket);
396
+ // Set up socket options
397
+ socket.setKeepAlive(true);
398
+ socket.setTimeout(this.options.socketTimeout);
399
+ // Explicitly set socket buffer sizes to prevent memory issues
400
+ socket.setNoDelay(true); // Disable Nagle's algorithm for better responsiveness
401
+ // Set limits on socket buffer size if supported by Node.js version
402
+ try {
403
+ // Here we set reasonable buffer limits to prevent memory exhaustion attacks
404
+ const highWaterMark = 64 * 1024; // 64 KB
405
+ // Note: Socket high water mark methods can't be set directly in newer Node.js versions
406
+ // These would need to be set during socket creation or with a different API
407
+ }
408
+ catch (error) {
409
+ // Ignore errors from older Node.js versions that don't support these methods
410
+ SmtpLogger.debug(`Could not set socket buffer limits: ${error instanceof Error ? error.message : String(error)}`);
411
+ }
412
+ // Track this IP connection
413
+ this.trackIPConnection(remoteAddress);
414
+ // Set up event handlers
415
+ this.setupSocketEventHandlers(socket);
416
+ // Create a session for this connection
417
+ this.smtpServer.getSessionManager().createSession(socket, true);
418
+ // Log the new secure connection using adaptive logger
419
+ adaptiveLogger.logConnection(socket, 'connect');
420
+ // Update adaptive logger with current connection count
421
+ adaptiveLogger.updateConnectionCount(this.connectionStats.activeConnections);
422
+ // Send greeting
423
+ this.sendGreeting(socket);
424
+ }
425
+ /**
426
+ * Set up event handlers for a socket with enhanced resource management
427
+ * @param socket - Client socket
428
+ */
429
+ setupSocketEventHandlers(socket) {
430
+ // Store existing socket event handlers before adding new ones
431
+ const existingDataHandler = socket.listeners('data')[0];
432
+ const existingCloseHandler = socket.listeners('close')[0];
433
+ const existingErrorHandler = socket.listeners('error')[0];
434
+ const existingTimeoutHandler = socket.listeners('timeout')[0];
435
+ // Remove existing event handlers if they exist
436
+ if (existingDataHandler)
437
+ socket.removeListener('data', existingDataHandler);
438
+ if (existingCloseHandler)
439
+ socket.removeListener('close', existingCloseHandler);
440
+ if (existingErrorHandler)
441
+ socket.removeListener('error', existingErrorHandler);
442
+ if (existingTimeoutHandler)
443
+ socket.removeListener('timeout', existingTimeoutHandler);
444
+ // Data event - process incoming data from the client with resource limits
445
+ let buffer = '';
446
+ let totalBytesReceived = 0;
447
+ socket.on('data', async (data) => {
448
+ try {
449
+ // Get current session and update activity timestamp
450
+ const session = this.smtpServer.getSessionManager().getSession(socket);
451
+ if (session) {
452
+ this.smtpServer.getSessionManager().updateSessionActivity(session);
453
+ }
454
+ // Check if we're in DATA receiving mode - handle differently
455
+ if (session && session.state === SmtpState.DATA_RECEIVING) {
456
+ // In DATA mode, pass raw chunks directly to command handler with special marker
457
+ // Don't line-buffer large email content
458
+ try {
459
+ const dataString = data.toString('utf8');
460
+ // Use a special prefix to indicate this is raw data, not a command line
461
+ // CRITICAL FIX: Must await to prevent async pile-up
462
+ await this.smtpServer.getCommandHandler().processCommand(socket, `__RAW_DATA__${dataString}`);
463
+ return;
464
+ }
465
+ catch (dataError) {
466
+ SmtpLogger.error(`Data handler error during DATA mode: ${dataError instanceof Error ? dataError.message : String(dataError)}`);
467
+ socket.destroy();
468
+ return;
469
+ }
470
+ }
471
+ // For command mode, continue with line-buffered processing
472
+ // Check buffer size limits to prevent memory attacks
473
+ totalBytesReceived += data.length;
474
+ if (buffer.length > this.options.bufferSizeLimit) {
475
+ // Buffer is too large, reject the connection
476
+ SmtpLogger.warn(`Buffer size limit exceeded: ${buffer.length} bytes for ${socket.remoteAddress}`);
477
+ this.sendResponse(socket, `${SmtpResponseCode.EXCEEDED_STORAGE} Message too large, disconnecting`);
478
+ socket.destroy();
479
+ return;
480
+ }
481
+ // Impose a total transfer limit to prevent DoS
482
+ if (totalBytesReceived > this.options.bufferSizeLimit * 2) {
483
+ SmtpLogger.warn(`Total transfer limit exceeded: ${totalBytesReceived} bytes for ${socket.remoteAddress}`);
484
+ this.sendResponse(socket, `${SmtpResponseCode.EXCEEDED_STORAGE} Transfer limit exceeded, disconnecting`);
485
+ socket.destroy();
486
+ return;
487
+ }
488
+ // Convert buffer to string safely with explicit encoding
489
+ const dataString = data.toString('utf8');
490
+ // Buffer incoming data
491
+ buffer += dataString;
492
+ // Process complete lines
493
+ let lineEndPos;
494
+ while ((lineEndPos = buffer.indexOf(SMTP_DEFAULTS.CRLF)) !== -1) {
495
+ // Extract a complete line
496
+ const line = buffer.substring(0, lineEndPos);
497
+ buffer = buffer.substring(lineEndPos + 2); // +2 to skip CRLF
498
+ // Check line length to prevent extremely long lines
499
+ if (line.length > 4096) { // 4KB line limit is reasonable for SMTP
500
+ SmtpLogger.warn(`Line length limit exceeded: ${line.length} bytes for ${socket.remoteAddress}`);
501
+ this.sendResponse(socket, `${SmtpResponseCode.SYNTAX_ERROR} Line too long, disconnecting`);
502
+ socket.destroy();
503
+ return;
504
+ }
505
+ // Process non-empty lines
506
+ if (line.length > 0) {
507
+ try {
508
+ // CRITICAL FIX: Must await processCommand to prevent async pile-up
509
+ // This was causing the busy loop with high CPU usage when many empty lines were processed
510
+ await this.smtpServer.getCommandHandler().processCommand(socket, line);
511
+ }
512
+ catch (error) {
513
+ // Handle any errors in command processing
514
+ SmtpLogger.error(`Command handler error: ${error instanceof Error ? error.message : String(error)}`);
515
+ this.sendResponse(socket, `${SmtpResponseCode.LOCAL_ERROR} Internal server error`);
516
+ // If there's a severe error, close the connection
517
+ if (error instanceof Error &&
518
+ (error.message.includes('fatal') || error.message.includes('critical'))) {
519
+ socket.destroy();
520
+ return;
521
+ }
522
+ }
523
+ }
524
+ }
525
+ // If buffer is getting too large without CRLF, it might be a DoS attempt
526
+ if (buffer.length > 10240) { // 10KB is a reasonable limit for a line without CRLF
527
+ SmtpLogger.warn(`Incomplete line too large: ${buffer.length} bytes for ${socket.remoteAddress}`);
528
+ this.sendResponse(socket, `${SmtpResponseCode.SYNTAX_ERROR} Incomplete line too large, disconnecting`);
529
+ socket.destroy();
530
+ }
531
+ }
532
+ catch (error) {
533
+ // Handle any unexpected errors during data processing
534
+ SmtpLogger.error(`Data handler error: ${error instanceof Error ? error.message : String(error)}`);
535
+ socket.destroy();
536
+ }
537
+ });
538
+ // Add drain event handler to manage flow control
539
+ socket.on('drain', () => {
540
+ // Socket buffer has been emptied, resume data flow if needed
541
+ if (socket.isPaused()) {
542
+ socket.resume();
543
+ SmtpLogger.debug(`Resumed socket for ${socket.remoteAddress} after drain`);
544
+ }
545
+ });
546
+ // Close event - clean up when connection is closed
547
+ socket.on('close', (hadError) => {
548
+ this.handleSocketClose(socket, hadError);
549
+ });
550
+ // Error event - handle socket errors
551
+ socket.on('error', (err) => {
552
+ this.handleSocketError(socket, err);
553
+ });
554
+ // Timeout event - handle socket timeouts
555
+ socket.on('timeout', () => {
556
+ this.handleSocketTimeout(socket);
557
+ });
558
+ }
559
+ /**
560
+ * Get the current connection count
561
+ * @returns Number of active connections
562
+ */
563
+ getConnectionCount() {
564
+ return this.activeConnections.size;
565
+ }
566
+ /**
567
+ * Check if the server has reached the maximum number of connections
568
+ * @returns True if max connections reached
569
+ */
570
+ hasReachedMaxConnections() {
571
+ return this.activeConnections.size >= this.options.maxConnections;
572
+ }
573
+ /**
574
+ * Close all active connections
575
+ */
576
+ closeAllConnections() {
577
+ const connectionCount = this.activeConnections.size;
578
+ if (connectionCount === 0) {
579
+ return;
580
+ }
581
+ SmtpLogger.info(`Closing all connections (count: ${connectionCount})`);
582
+ for (const socket of this.activeConnections) {
583
+ try {
584
+ // Send service closing notification
585
+ this.sendServiceClosing(socket);
586
+ // End the socket gracefully
587
+ socket.end();
588
+ // Force destroy after a short delay if not already destroyed
589
+ const destroyTimer = setTimeout(() => {
590
+ if (!socket.destroyed) {
591
+ socket.destroy();
592
+ }
593
+ this.cleanupTimers.delete(destroyTimer);
594
+ }, 100);
595
+ this.cleanupTimers.add(destroyTimer);
596
+ }
597
+ catch (error) {
598
+ SmtpLogger.error(`Error closing connection: ${error instanceof Error ? error.message : String(error)}`);
599
+ // Force destroy on error
600
+ try {
601
+ socket.destroy();
602
+ }
603
+ catch (e) {
604
+ // Ignore destroy errors
605
+ }
606
+ }
607
+ }
608
+ // Clear active connections
609
+ this.activeConnections.clear();
610
+ // Stop resource monitoring to prevent hanging timers
611
+ if (this.resourceCheckInterval) {
612
+ clearInterval(this.resourceCheckInterval);
613
+ this.resourceCheckInterval = null;
614
+ }
615
+ }
616
+ /**
617
+ * Handle socket close event
618
+ * @param socket - Client socket
619
+ * @param hadError - Whether the socket was closed due to error
620
+ */
621
+ handleSocketClose(socket, hadError) {
622
+ try {
623
+ // Update connection statistics
624
+ this.connectionStats.closedConnections++;
625
+ this.connectionStats.activeConnections = this.activeConnections.size - 1;
626
+ // Get socket details for logging
627
+ const socketDetails = getSocketDetails(socket);
628
+ const socketId = `${socketDetails.remoteAddress}:${socketDetails.remotePort}`;
629
+ // Log with appropriate level based on whether there was an error
630
+ if (hadError) {
631
+ SmtpLogger.warn(`Socket closed with error: ${socketId}`);
632
+ }
633
+ else {
634
+ SmtpLogger.debug(`Socket closed normally: ${socketId}`);
635
+ }
636
+ // Get the session before removing it
637
+ const session = this.smtpServer.getSessionManager().getSession(socket);
638
+ // Remove from active connections
639
+ this.activeConnections.delete(socket);
640
+ // Remove from session manager
641
+ this.smtpServer.getSessionManager().removeSession(socket);
642
+ // Cancel any timeout ID stored in the session
643
+ if (session?.dataTimeoutId) {
644
+ clearTimeout(session.dataTimeoutId);
645
+ }
646
+ // Log connection close with session details if available
647
+ adaptiveLogger.logConnection(socket, 'close', session);
648
+ // Update adaptive logger with new connection count
649
+ adaptiveLogger.updateConnectionCount(this.connectionStats.activeConnections);
650
+ }
651
+ catch (error) {
652
+ // Handle any unexpected errors during cleanup
653
+ SmtpLogger.error(`Error in handleSocketClose: ${error instanceof Error ? error.message : String(error)}`);
654
+ // Ensure socket is removed from active connections even if an error occurs
655
+ this.activeConnections.delete(socket);
656
+ }
657
+ }
658
+ /**
659
+ * Handle socket error event
660
+ * @param socket - Client socket
661
+ * @param error - Error object
662
+ */
663
+ handleSocketError(socket, error) {
664
+ try {
665
+ // Update connection statistics
666
+ this.connectionStats.erroredConnections++;
667
+ // Get socket details for context
668
+ const socketDetails = getSocketDetails(socket);
669
+ const socketId = `${socketDetails.remoteAddress}:${socketDetails.remotePort}`;
670
+ // Get the session
671
+ const session = this.smtpServer.getSessionManager().getSession(socket);
672
+ // Detailed error logging with context information
673
+ SmtpLogger.error(`Socket error for ${socketId}: ${error.message}`, {
674
+ errorCode: error.code,
675
+ errorStack: error.stack,
676
+ sessionId: session?.id,
677
+ sessionState: session?.state,
678
+ remoteAddress: socketDetails.remoteAddress,
679
+ remotePort: socketDetails.remotePort
680
+ });
681
+ // Log the error for connection tracking using adaptive logger
682
+ adaptiveLogger.logConnection(socket, 'error', session, error);
683
+ // Cancel any timeout ID stored in the session
684
+ if (session?.dataTimeoutId) {
685
+ clearTimeout(session.dataTimeoutId);
686
+ }
687
+ // Close the socket if not already closed
688
+ if (!socket.destroyed) {
689
+ socket.destroy();
690
+ }
691
+ // Remove from active connections (cleanup after error)
692
+ this.activeConnections.delete(socket);
693
+ // Remove from session manager
694
+ this.smtpServer.getSessionManager().removeSession(socket);
695
+ }
696
+ catch (handlerError) {
697
+ // Meta-error handling (errors in the error handler)
698
+ SmtpLogger.error(`Error in handleSocketError: ${handlerError instanceof Error ? handlerError.message : String(handlerError)}`);
699
+ // Ensure socket is destroyed and removed from active connections
700
+ if (!socket.destroyed) {
701
+ socket.destroy();
702
+ }
703
+ this.activeConnections.delete(socket);
704
+ }
705
+ }
706
+ /**
707
+ * Handle socket timeout event
708
+ * @param socket - Client socket
709
+ */
710
+ handleSocketTimeout(socket) {
711
+ try {
712
+ // Update connection statistics
713
+ this.connectionStats.timedOutConnections++;
714
+ // Get socket details for context
715
+ const socketDetails = getSocketDetails(socket);
716
+ const socketId = `${socketDetails.remoteAddress}:${socketDetails.remotePort}`;
717
+ // Get the session
718
+ const session = this.smtpServer.getSessionManager().getSession(socket);
719
+ // Get timing information for better debugging
720
+ const now = Date.now();
721
+ const idleTime = session?.lastActivity ? now - session.lastActivity : 'unknown';
722
+ if (session) {
723
+ // Log the timeout with extended details
724
+ SmtpLogger.warn(`Socket timeout from ${session.remoteAddress}`, {
725
+ sessionId: session.id,
726
+ remoteAddress: session.remoteAddress,
727
+ state: session.state,
728
+ timeout: this.options.socketTimeout,
729
+ idleTime: idleTime,
730
+ emailState: session.envelope?.mailFrom ? 'has-sender' : 'no-sender',
731
+ recipientCount: session.envelope?.rcptTo?.length || 0
732
+ });
733
+ // Cancel any timeout ID stored in the session
734
+ if (session.dataTimeoutId) {
735
+ clearTimeout(session.dataTimeoutId);
736
+ }
737
+ // Send timeout notification to client
738
+ this.sendResponse(socket, `${SmtpResponseCode.SERVICE_NOT_AVAILABLE} Connection timeout - closing connection`);
739
+ }
740
+ else {
741
+ // Log timeout without session context
742
+ SmtpLogger.warn(`Socket timeout without session from ${socketId}`);
743
+ }
744
+ // Close the socket gracefully
745
+ try {
746
+ socket.end();
747
+ // Set a forced close timeout in case socket.end() doesn't close the connection
748
+ const timeoutDestroyTimer = setTimeout(() => {
749
+ if (!socket.destroyed) {
750
+ SmtpLogger.warn(`Forcing destroy of timed out socket: ${socketId}`);
751
+ socket.destroy();
752
+ }
753
+ this.cleanupTimers.delete(timeoutDestroyTimer);
754
+ }, 5000); // 5 second grace period for socket to end properly
755
+ this.cleanupTimers.add(timeoutDestroyTimer);
756
+ }
757
+ catch (error) {
758
+ SmtpLogger.error(`Error ending timed out socket: ${error instanceof Error ? error.message : String(error)}`);
759
+ // Ensure socket is destroyed even if end() fails
760
+ if (!socket.destroyed) {
761
+ socket.destroy();
762
+ }
763
+ }
764
+ // Clean up resources
765
+ this.activeConnections.delete(socket);
766
+ this.smtpServer.getSessionManager().removeSession(socket);
767
+ }
768
+ catch (handlerError) {
769
+ // Handle any unexpected errors during timeout handling
770
+ SmtpLogger.error(`Error in handleSocketTimeout: ${handlerError instanceof Error ? handlerError.message : String(handlerError)}`);
771
+ // Ensure socket is destroyed and removed from tracking
772
+ if (!socket.destroyed) {
773
+ socket.destroy();
774
+ }
775
+ this.activeConnections.delete(socket);
776
+ }
777
+ }
778
+ /**
779
+ * Reject a connection
780
+ * @param socket - Client socket
781
+ * @param reason - Reason for rejection
782
+ */
783
+ rejectConnection(socket, reason) {
784
+ // Log the rejection
785
+ const socketDetails = getSocketDetails(socket);
786
+ SmtpLogger.warn(`Connection rejected from ${socketDetails.remoteAddress}:${socketDetails.remotePort}: ${reason}`);
787
+ // Send rejection message
788
+ this.sendResponse(socket, `${SmtpResponseCode.SERVICE_NOT_AVAILABLE} ${this.options.hostname} Service temporarily unavailable - ${reason}`);
789
+ // Close the socket
790
+ try {
791
+ socket.end();
792
+ }
793
+ catch (error) {
794
+ SmtpLogger.error(`Error ending rejected socket: ${error instanceof Error ? error.message : String(error)}`);
795
+ }
796
+ }
797
+ /**
798
+ * Send greeting message
799
+ * @param socket - Client socket
800
+ */
801
+ sendGreeting(socket) {
802
+ const greeting = `${SmtpResponseCode.SERVICE_READY} ${this.options.hostname} ESMTP service ready`;
803
+ this.sendResponse(socket, greeting);
804
+ }
805
+ /**
806
+ * Send service closing notification
807
+ * @param socket - Client socket
808
+ */
809
+ sendServiceClosing(socket) {
810
+ const message = `${SmtpResponseCode.SERVICE_CLOSING} ${this.options.hostname} Service closing transmission channel`;
811
+ this.sendResponse(socket, message);
812
+ }
813
+ /**
814
+ * Send response to client
815
+ * @param socket - Client socket
816
+ * @param response - Response to send
817
+ */
818
+ sendResponse(socket, response) {
819
+ // Check if socket is still writable before attempting to write
820
+ if (socket.destroyed || socket.readyState !== 'open' || !socket.writable) {
821
+ SmtpLogger.debug(`Skipping response to closed/destroyed socket: ${response}`, {
822
+ remoteAddress: socket.remoteAddress,
823
+ remotePort: socket.remotePort,
824
+ destroyed: socket.destroyed,
825
+ readyState: socket.readyState,
826
+ writable: socket.writable
827
+ });
828
+ return;
829
+ }
830
+ try {
831
+ socket.write(`${response}${SMTP_DEFAULTS.CRLF}`);
832
+ adaptiveLogger.logResponse(response, socket);
833
+ }
834
+ catch (error) {
835
+ // Log error and destroy socket
836
+ SmtpLogger.error(`Error sending response: ${error instanceof Error ? error.message : String(error)}`, {
837
+ response,
838
+ remoteAddress: socket.remoteAddress,
839
+ remotePort: socket.remotePort,
840
+ error: error instanceof Error ? error : new Error(String(error))
841
+ });
842
+ socket.destroy();
843
+ }
844
+ }
845
+ /**
846
+ * Handle a new connection (interface requirement)
847
+ */
848
+ async handleConnection(socket, secure) {
849
+ if (secure) {
850
+ this.handleNewSecureConnection(socket);
851
+ }
852
+ else {
853
+ this.handleNewConnection(socket);
854
+ }
855
+ }
856
+ /**
857
+ * Check if accepting new connections (interface requirement)
858
+ */
859
+ canAcceptConnection() {
860
+ return !this.hasReachedMaxConnections();
861
+ }
862
+ /**
863
+ * Clean up resources
864
+ */
865
+ destroy() {
866
+ // Clear resource monitoring interval
867
+ if (this.resourceCheckInterval) {
868
+ clearInterval(this.resourceCheckInterval);
869
+ this.resourceCheckInterval = null;
870
+ }
871
+ // Clear all cleanup timers
872
+ for (const timer of this.cleanupTimers) {
873
+ clearTimeout(timer);
874
+ }
875
+ this.cleanupTimers.clear();
876
+ // Close all active connections
877
+ this.closeAllConnections();
878
+ // Clear maps
879
+ this.activeConnections.clear();
880
+ this.ipConnections.clear();
881
+ // Reset connection stats
882
+ this.connectionStats = {
883
+ totalConnections: 0,
884
+ activeConnections: 0,
885
+ peakConnections: 0,
886
+ rejectedConnections: 0,
887
+ closedConnections: 0,
888
+ erroredConnections: 0,
889
+ timedOutConnections: 0
890
+ };
891
+ SmtpLogger.debug('ConnectionManager destroyed');
892
+ }
893
+ }
894
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdGlvbi1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvbWFpbC9kZWxpdmVyeS9zbXRwc2VydmVyL2Nvbm5lY3Rpb24tbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBRS9DLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUvRTs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQXlENUI7OztPQUdHO0lBQ0gsWUFBWSxVQUF1QjtRQXZEbkM7O1dBRUc7UUFDSyxzQkFBaUIsR0FBb0QsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUV2Rjs7V0FFRztRQUNLLG9CQUFlLEdBQUc7WUFDeEIsZ0JBQWdCLEVBQUUsQ0FBQztZQUNuQixpQkFBaUIsRUFBRSxDQUFDO1lBQ3BCLGVBQWUsRUFBRSxDQUFDO1lBQ2xCLG1CQUFtQixFQUFFLENBQUM7WUFDdEIsaUJBQWlCLEVBQUUsQ0FBQztZQUNwQixrQkFBa0IsRUFBRSxDQUFDO1lBQ3JCLG1CQUFtQixFQUFFLENBQUM7U0FDdkIsQ0FBQztRQUVGOztXQUVHO1FBQ0ssa0JBQWEsR0FJaEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUVmOztXQUVHO1FBQ0ssMEJBQXFCLEdBQTBCLElBQUksQ0FBQztRQUU1RDs7V0FFRztRQUNLLGtCQUFhLEdBQXdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFxQnJELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxD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