atomicshop 2.20.8__py3-none-any.whl → 2.21.1__py3-none-any.whl

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.

Potentially problematic release.


This version of atomicshop might be problematic. Click here for more details.

@@ -11,7 +11,6 @@ import multiprocessing
11
11
  from ...print_api import print_api
12
12
  from ..loggingw import loggingw
13
13
  from ..psutilw import networks
14
- from ... import queues
15
14
  from ...basics import booleans, tracebacks
16
15
  from ...file_io import csvs
17
16
 
@@ -145,18 +144,15 @@ class DnsServer:
145
144
  # noinspection PyPep8Naming
146
145
  def __init__(
147
146
  self,
148
- listening_interface: str,
149
- listening_port: int,
147
+ listening_address: str,
150
148
  log_directory_path: str,
151
149
  backupCount_log_files_x_days: int = 0,
152
150
  forwarding_dns_service_ipv4: str = '8.8.8.8',
153
151
  forwarding_dns_service_port: int = 53,
154
- resolve_to_tcp_server_only_tcp_resolve_domains: bool = False,
155
- resolve_to_tcp_server_all_domains: bool = False,
156
- resolve_regular: bool = False,
152
+ resolve_by_engine: tuple[bool, list] = (False, None),
153
+ resolve_regular_pass_thru: bool = False,
154
+ resolve_all_domains_to_ipv4: tuple[bool, str] = (False, '127.0.0.1'),
157
155
  offline_mode: bool = False,
158
- tcp_target_server_ipv4: str = '127.0.0.1',
159
- tcp_resolve_domain_list: list = None,
160
156
  request_domain_queue: multiprocessing.Queue = None,
161
157
  buffer_size_receive: int = 8192,
162
158
  response_ttl: int = 60,
@@ -169,9 +165,8 @@ class DnsServer:
169
165
  """
170
166
  Initialize the DNS Server object with all the necessary settings.
171
167
 
172
- :param listening_interface: str: Interface that the DNS Server will listen on.
173
- Example: '0.0.0.0'. For all interfaces.
174
- :param listening_port: int: Port number that the DNS Server will listen on.
168
+ :param listening_address: str: Interface and a port that the DNS Server will listen on.
169
+ Example: '0.0.0.0:53'. For all interfaces on port 53.
175
170
  :param log_directory_path: str: Path to the directory where the logs will be saved.
176
171
  :param backupCount_log_files_x_days: int: How many days the log files will be kept.
177
172
  Default is 0, which means that the log files will be kept indefinitely.
@@ -180,15 +175,14 @@ class DnsServer:
180
175
  Example: '8.8.8.8'. For Google DNS Service.
181
176
  :param forwarding_dns_service_port: int: Port number of the DNS Service that will be used for resolving.
182
177
  Default is 53.
183
- :param resolve_to_tcp_server_only_tcp_resolve_domains: bool: If the DNS Server should route only the
184
- domains from 'tcp_resolve_domain_list' to the TCP Server in 'tcp_target_server_ipv4'.
185
- :param resolve_to_tcp_server_all_domains: bool: If the DNS Server should route all domains to the TCP Server.
186
- :param resolve_regular: bool: If the DNS Server should resolve all the domains to the Live DNS Service.
178
+ :param resolve_by_engine: tuple(boolean to enable the feature, list of engines).
179
+ True, The list of predefined engines will be used to resolve the domains.
180
+ Each list has a list of specific domains that will be routed to specified destination IPv4 address.
181
+ :param resolve_all_domains_to_ipv4: bool: If the DNS Server should resolve all the domains
182
+ to the provided origin DNS Service without altering the DNS request/response.
183
+ :param resolve_all_domains_to_ipv4: tuple(boolean to enable the feature, string IPv4 of the target).
184
+ True, the DNS Server will route all domains to the specified IPv4.
187
185
  :param offline_mode: bool: If the DNS Server should work in offline mode.
188
- :param tcp_target_server_ipv4: str: IPv4 address of the TCP Server that the specified booleans will resolve
189
- the domains to.
190
- :param tcp_resolve_domain_list: list: List of domains that will be resolved to the TCP Server.
191
- This means that all the requests will be resolved to the specified offline IPv4 address.
192
186
  :param request_domain_queue: multiprocessing Queue to pass all the requested domains that hit the DNS
193
187
  :param buffer_size_receive: int: Buffer size of the connection while receiving messages.
194
188
  :param response_ttl: int, Time to live of the DNS Response that will be returned. Default is 60 seconds.
@@ -205,17 +199,15 @@ class DnsServer:
205
199
  You can pass only one of the following: 'logger', 'logging_queue'.
206
200
  """
207
201
 
208
- self.listening_interface: str = listening_interface
209
- self.listening_port: int = listening_port
202
+ self.listening_address: str = listening_address
210
203
  self.log_directory_path: str = log_directory_path
204
+ self.backupCount_log_files_x_days: int = backupCount_log_files_x_days
211
205
  self.forwarding_dns_service_ipv4: str = forwarding_dns_service_ipv4
212
206
  self.forwarding_dns_service_port: int = forwarding_dns_service_port
213
- self.tcp_target_server_ipv4: str = tcp_target_server_ipv4
214
- self.tcp_resolve_domain_list: list = tcp_resolve_domain_list
207
+ self.resolve_by_engine: tuple[bool, list] = resolve_by_engine
208
+ self.resolve_regular_pass_thru: bool = resolve_regular_pass_thru
209
+ self.resolve_all_domains_to_ipv4: tuple[bool, str] = resolve_all_domains_to_ipv4
215
210
  self.offline_mode: bool = offline_mode
216
- self.resolve_to_tcp_server_only_tcp_resolve_domains: bool = resolve_to_tcp_server_only_tcp_resolve_domains
217
- self.resolve_to_tcp_server_all_domains: bool = resolve_to_tcp_server_all_domains
218
- self.resolve_regular: bool = resolve_regular
219
211
  self.request_domain_queue: multiprocessing.Queue = request_domain_queue
220
212
  self.buffer_size_receive: int = buffer_size_receive
221
213
  self.response_ttl: int = response_ttl
@@ -227,10 +219,27 @@ class DnsServer:
227
219
  if logger and logging_queue:
228
220
  raise ValueError("You can pass only one of the following: 'logger', 'logging_queue'.")
229
221
 
230
- if not tcp_resolve_domain_list:
231
- self.tcp_resolve_domain_list = list()
232
- else:
233
- self.tcp_resolve_domain_list = tcp_resolve_domain_list
222
+ self.listening_interface, listening_port = self.listening_address.split(':')
223
+ self.listening_interface: str
224
+ self.listening_port: int = int(listening_port)
225
+ self.resolve_by_engine_enable, self.engine_list = self.resolve_by_engine
226
+ self.resolve_by_engine_enable: bool
227
+ self.engine_list: list
228
+ self.resolve_all_domains_to_ipv4_enable, self.resolve_all_domains_target = self.resolve_all_domains_to_ipv4
229
+ self.resolve_all_domains_to_ipv4_enable: bool
230
+ self.resolve_all_domains_target: str
231
+
232
+ self.intercept_domain_list: list = list()
233
+ for engine in self.engine_list:
234
+ # If the engine is not a reference engine.
235
+ if engine.engine_name != '__reference_general':
236
+ # Get the domains from the engine.
237
+ self.intercept_domain_list.extend(engine.domain_list)
238
+
239
+ # If the engine has no_sni section enabled, get the domains from it.
240
+ if engine.no_sni.serve_domain_on_address_enable:
241
+ for domain, ip_address in engine.no_sni.serve_domain_on_address_dict.items():
242
+ self.intercept_domain_list.append(domain)
234
243
 
235
244
  # Settings for static DNS Responses in offline mode.
236
245
  self.offline_route_ipv4: str = '10.10.10.10'
@@ -270,7 +279,7 @@ class DnsServer:
270
279
  add_timedfile_with_internal_queue=True,
271
280
  formatter_streamhandler='DEFAULT',
272
281
  formatter_filehandler='DEFAULT',
273
- backupCount=backupCount_log_files_x_days
282
+ backupCount=self.backupCount_log_files_x_days
274
283
  )
275
284
  elif logger:
276
285
  # Create child logger for the provided logger with the module's name.
@@ -288,10 +297,9 @@ class DnsServer:
288
297
  try:
289
298
  booleans.is_only_1_true_in_list(
290
299
  booleans_list_of_tuples=[
291
- (self.resolve_to_tcp_server_only_tcp_resolve_domains,
292
- 'resolve_to_tcp_server_only_tcp_resolve_domains'),
293
- (self.resolve_to_tcp_server_all_domains, 'resolve_to_tcp_server_all_domains'),
294
- (self.resolve_regular, 'resolve_regular')
300
+ (self.resolve_by_engine_enable, 'resolve_by_engine_enable'),
301
+ (self.resolve_regular_pass_thru, 'resolve_regular_pass_thru'),
302
+ (self.resolve_all_domains_to_ipv4_enable, 'resolve_all_domains_to_ipv4_enable')
295
303
  ],
296
304
  raise_if_all_false=True
297
305
  )
@@ -345,19 +353,19 @@ class DnsServer:
345
353
  known_a_records_ipv4_dict: dict = dict()
346
354
 
347
355
  # Check if 'route_to_tcp_server_only_engine_domains' was set to 'True' and output message accordingly.
348
- if self.resolve_to_tcp_server_only_tcp_resolve_domains:
349
- message = "Routing only engine domains to Built-in TCP Server."
356
+ if self.resolve_by_engine_enable:
357
+ message = "Routing engine domains to the specified IPv4 targets."
350
358
  print_api(message, logger=self.logger)
351
359
 
352
- message = f"Current engine domains: {self.tcp_resolve_domain_list}"
360
+ message = f"Current all engines domains: {self.intercept_domain_list}"
353
361
  print_api(message, logger=self.logger, color='blue')
354
362
 
355
- if self.resolve_to_tcp_server_all_domains:
356
- message = "Routing all domains to Built-in TCP Server."
363
+ if self.resolve_all_domains_to_ipv4_enable:
364
+ message = f"Routing all domains to the specified target: [{self.resolve_all_domains_target}]"
357
365
  print_api(message, logger=self.logger, color='blue')
358
366
 
359
- if self.resolve_regular:
360
- message = f"Routing all domains to Live DNS Service: {self.forwarding_dns_service_ipv4}"
367
+ if self.resolve_regular_pass_thru:
368
+ message = f"Routing all domains to the specified Origin DNS Service: {self.forwarding_dns_service_ipv4}:{self.forwarding_dns_service_port}"
361
369
  print_api(message, logger=self.logger, color='blue')
362
370
 
363
371
  # The list that will hold all the threads that can be joined later
@@ -462,10 +470,10 @@ class DnsServer:
462
470
  if qtype_string == "A":
463
471
  # Check if 'resolve_to_tcp_server_only_tcp_resolve_domains' is set to 'True'.
464
472
  # If so, we need to check if the incoming domain contain any of the domains in the list.
465
- if self.resolve_to_tcp_server_only_tcp_resolve_domains:
473
+ if self.resolve_by_engine_enable:
466
474
  # If current query domain (+ subdomains) CONTAIN any of the domains from modules config
467
475
  # files and current request contains "A" (IPv4) record.
468
- if any(x in question_domain for x in self.tcp_resolve_domain_list):
476
+ if any(x in question_domain for x in self.intercept_domain_list):
469
477
  # If incoming domain contains any of the 'engine_domains' then domain will
470
478
  # be forwarded to our TCP Server.
471
479
  forward_to_tcp_server = True
@@ -474,12 +482,12 @@ class DnsServer:
474
482
 
475
483
  # If 'route_to_tcp_server_all_domains' was set to 'False' in 'config.ini' file then
476
484
  # we'll forward all 'A' records domains to the Built-in TCP Server.
477
- if self.resolve_to_tcp_server_all_domains:
485
+ if self.resolve_all_domains_to_ipv4_enable:
478
486
  forward_to_tcp_server = True
479
487
 
480
488
  # If 'regular_resolving' was set to 'True' in 'config.ini' file then
481
489
  # we'll forward all 'A' records domains to the Live DNS Service.
482
- if self.resolve_regular:
490
+ if self.resolve_regular_pass_thru:
483
491
  forward_to_tcp_server = False
484
492
 
485
493
  # If incoming record is not an "A" record, then it will not be forwarded to our TCP Server.
@@ -488,9 +496,33 @@ class DnsServer:
488
496
 
489
497
  # If 'forward_to_tcp_server' is 'True' we'll resolve the record with our TCP Server IP address.
490
498
  if forward_to_tcp_server:
491
- # If the request is forwarded to TCP server, then we'll put the domain in the domain queue.
492
- # self.request_domain_queue.put(question_domain)
493
- self.request_domain_queue.put(question_domain)
499
+ if self.resolve_by_engine_enable:
500
+ for engine in self.engine_list:
501
+ # Check if the incoming domain contain any of the domains in the list.
502
+ if any(x in question_domain for x in engine.domain_list):
503
+ # Get the target IP address from the engine.
504
+ resolved_target_ipv4 = engine.dns_target
505
+
506
+ if engine.no_sni.get_from_dns:
507
+ # If the request is forwarded to TCP server, then we'll put the domain in the domain queue.
508
+ # self.request_domain_queue.put(question_domain)
509
+ self.request_domain_queue.put(question_domain)
510
+
511
+ break
512
+
513
+ if engine.no_sni.serve_domain_on_address_enable:
514
+ if question_domain in engine.no_sni.serve_domain_on_address_dict:
515
+ ip_port_address: str = engine.no_sni.serve_domain_on_address_dict[question_domain]
516
+ target_ip = ip_port_address.split(':')[0]
517
+ resolved_target_ipv4 = target_ip
518
+ break
519
+
520
+ if self.resolve_all_domains_to_ipv4_enable:
521
+ # Assign the target IPv4 address to the resolved target IPv4 variable.
522
+ resolved_target_ipv4 = self.resolve_all_domains_target
523
+
524
+ # Put the domain in the domain queue.
525
+ self.request_domain_queue.put(question_domain)
494
526
 
495
527
  # Make DNS response that will refer TCP traffic to our server
496
528
  dns_built_response = DNSRecord(
@@ -499,7 +531,7 @@ class DnsServer:
499
531
  # q=DNSQuestion(question_domain),
500
532
  q=dns_object.q,
501
533
  a=RR(question_domain,
502
- rdata=A(self.tcp_target_server_ipv4),
534
+ rdata=A(resolved_target_ipv4),
503
535
  ttl=self.response_ttl)
504
536
  )
505
537
  # Encode the response that was built above to legit DNS Response
@@ -883,19 +915,15 @@ class DnsServer:
883
915
 
884
916
  # noinspection PyPep8Naming
885
917
  def start_dns_server_multiprocessing_worker(
886
- listening_interface: str,
887
- listening_port: int,
918
+ listening_address: str,
888
919
  log_directory_path: str,
889
920
  backupCount_log_files_x_days: int,
890
921
  forwarding_dns_service_ipv4: str,
891
- tcp_target_server_ipv4: str,
892
- # Passing the engine domain list to DNS server to work with.
893
- # 'list' function re-initializes the current list, or else it will be the same instance object.
894
- tcp_resolve_domain_list: list,
922
+ forwarding_dns_service_port: int,
923
+ resolve_by_engine: tuple[bool, list],
924
+ resolve_regular_pass_thru: bool,
925
+ resolve_all_domains_to_ipv4: tuple[bool, str],
895
926
  offline_mode: bool,
896
- resolve_to_tcp_server_only_tcp_resolve_domains: bool,
897
- resolve_to_tcp_server_all_domains: bool,
898
- resolve_regular: bool,
899
927
  cache_timeout_minutes: int,
900
928
  request_domain_queue: multiprocessing.Queue,
901
929
  logging_queue: multiprocessing.Queue,
@@ -907,19 +935,15 @@ def start_dns_server_multiprocessing_worker(
907
935
 
908
936
  try:
909
937
  dns_server_instance = DnsServer(
910
- listening_interface=listening_interface,
911
- listening_port=listening_port,
938
+ listening_address=listening_address,
912
939
  log_directory_path=log_directory_path,
913
940
  backupCount_log_files_x_days=backupCount_log_files_x_days,
914
941
  forwarding_dns_service_ipv4=forwarding_dns_service_ipv4,
915
- tcp_target_server_ipv4=tcp_target_server_ipv4,
916
- # Passing the engine domain list to DNS server to work with.
917
- # 'list' function re-initializes the current list, or else it will be the same instance object.
918
- tcp_resolve_domain_list=tcp_resolve_domain_list,
942
+ forwarding_dns_service_port=forwarding_dns_service_port,
943
+ resolve_by_engine=resolve_by_engine,
944
+ resolve_regular_pass_thru=resolve_regular_pass_thru,
945
+ resolve_all_domains_to_ipv4=resolve_all_domains_to_ipv4,
919
946
  offline_mode=offline_mode,
920
- resolve_to_tcp_server_only_tcp_resolve_domains=resolve_to_tcp_server_only_tcp_resolve_domains,
921
- resolve_to_tcp_server_all_domains=resolve_to_tcp_server_all_domains,
922
- resolve_regular=resolve_regular,
923
947
  cache_timeout_minutes=cache_timeout_minutes,
924
948
  request_domain_queue=request_domain_queue,
925
949
  logging_queue=logging_queue,
@@ -28,7 +28,7 @@ class SocketClient:
28
28
  service_port: int,
29
29
  tls: bool = False,
30
30
  connection_ip=None,
31
- dns_servers_list=None,
31
+ dns_servers_list: list[str] = None,
32
32
  logger: logging.Logger = None,
33
33
  custom_pem_client_certificate_file_path: str = None,
34
34
  enable_sslkeylogfile_env_to_client_ssl_context: bool = False
@@ -5,7 +5,9 @@ from pathlib import Path
5
5
  import logging
6
6
  import socket
7
7
  import multiprocessing
8
+ import queue
8
9
 
10
+ from ...mitm import initialize_engines
9
11
  from ..psutilw import networks
10
12
  from ..certauthw import certauthw
11
13
  from ..loggingw import loggingw
@@ -32,7 +34,6 @@ SNI_QUEUE = queues.NonBlockQueue()
32
34
  class SocketWrapper:
33
35
  def __init__(
34
36
  self,
35
- listening_address_list: list[str],
36
37
  forwarding_dns_service_ipv4_list___only_for_localhost: list = None,
37
38
  ca_certificate_name: str = None,
38
39
  ca_certificate_filepath: str = None,
@@ -69,15 +70,14 @@ class SocketWrapper:
69
70
  exceptions_logger: loggingw.ExceptionCsvLogger = None,
70
71
  statistics_logs_directory: str = None,
71
72
  request_domain_from_dns_server_queue: multiprocessing.Queue = None,
72
- engines_domains: dict = None,
73
- engine_no_sni_domain: str = None
73
+ no_engine_usage_enable: bool = False,
74
+ no_engines_listening_address_list: list[str] = None,
75
+ engines_list: list[initialize_engines.ModuleCategory] = None
74
76
  ):
75
77
  """
76
78
  Socket Wrapper class that will be used to create sockets, listen on them, accept connections and send them to
77
79
  new threads.
78
80
 
79
- :param listening_address_list: list, of ips+ports that will be listened on.
80
- Example: ['0.0.0.0:443', '0.0.0.0:80']
81
81
  :param ca_certificate_name: CA certificate name.
82
82
  :param ca_certificate_filepath: CA certificate file path with '.pem' extension.
83
83
  :param ca_certificate_crt_filepath: CA certificate file path with '.crt' extension.
@@ -166,19 +166,24 @@ class SocketWrapper:
166
166
  to get the domain name that was requested from the DNS server (atomicshop.wrappers.socketw.dns_server).
167
167
  This is used to get the domain name that got to the DNS server and set it to the socket in case SNI
168
168
  was empty (in the SNIHandler class to set the 'server_hostname' for the socket).
169
- :param engines_domains: dictionary of engines that will be used to process the requests. Example:
170
- [
171
- {'this_is_engine_name': ['example.com', 'example.org']},
172
- {'this_is_engine_name2': ['example2.com', 'example2.org']}
173
- ]
174
-
175
- the 'engine_name' for statistics.csv file will be taken from the key of the dictionary, while correlated
176
- by the domain name from the list in the dictionary.
177
- :param engine_no_sni_domain: string, domain name that will be used if there is no SNI in the request,
178
- and no domain hit the dns server. This is used to set the 'server_hostname' for the socket.
169
+ :param no_engine_usage_enable: boolean, if True, 'engines_list' will be used to listen on the addresses,
170
+ but the "no_engines_listening_address_list" parameter will be used instead.
171
+ :param no_engines_listening_address_list: list, of ips+ports that will be listened on.
172
+ Example: ['0.0.0.0:443', '0.0.0.0:80']
173
+ :param engines_list: list, of engines that will be used to process the requests. Structure of engine_config.toml:
174
+ [engine]
175
+ "domains" = ["example.com"]
176
+
177
+ [mtls]
178
+ # "subdomain.domain.com" = "file_name_in_current_dir.pem"
179
+
180
+ [no_sni]
181
+ #get_from_dns = 1 # Blocking, the accept function will wait until the domain is received from DNS.
182
+ #get_from_engine = 0
183
+ #try_to_get_from_dns_on_empty_get_from_engine = 0 # Non-blocking, on empty DNS server queue, accept() will connect to the domain from below.
184
+ #"domain" = "example.com"
179
185
  """
180
186
 
181
- self.listening_address_list: list[str] = listening_address_list
182
187
  self.ca_certificate_name: str = ca_certificate_name
183
188
  self.ca_certificate_filepath: str = ca_certificate_filepath
184
189
  self.ca_certificate_crt_filepath: str = ca_certificate_crt_filepath
@@ -211,8 +216,21 @@ class SocketWrapper:
211
216
  self.forwarding_dns_service_ipv4_list___only_for_localhost = (
212
217
  forwarding_dns_service_ipv4_list___only_for_localhost)
213
218
  self.request_domain_from_dns_server_queue: multiprocessing.Queue = request_domain_from_dns_server_queue
214
- self.engines_domains: dict = engines_domains
215
- self.engine_no_sni_domain: str = engine_no_sni_domain
219
+ self.no_engine_usage_enable: bool = no_engine_usage_enable
220
+ self.no_engines_listening_address_list: list[str] = no_engines_listening_address_list
221
+ self.engines_list: list[initialize_engines.ModuleCategory] = engines_list
222
+
223
+ # dictionary of engines that will be used to find the engine name. Example:
224
+ # [{'this_is_engine_name': ['example.com', 'example.org']},
225
+ # {'this_is_engine_name2': ['example2.com', 'example2.org']}]
226
+ self.engines_domains: dict = dict()
227
+ for engine in self.engines_list:
228
+ self.engines_domains[engine.engine_name] = engine.domain_list
229
+
230
+ if engine.no_sni.serve_domain_on_address_enable:
231
+ for domain, ip_port_address in engine.no_sni.serve_domain_on_address_dict.items():
232
+ if domain not in self.engines_domains[engine.engine_name]:
233
+ self.engines_domains[engine.engine_name].append(domain)
216
234
 
217
235
  self.socket_object = None
218
236
 
@@ -275,6 +293,13 @@ class SocketWrapper:
275
293
  "You can't set both [sni_use_default_callback_function = True] and [sni_custom_callback_function]."
276
294
  raise SocketWrapperConfigurationValuesError(message)
277
295
 
296
+ if self.no_engine_usage_enable and not self.no_engines_listening_address_list:
297
+ message = "You set [no_engine_usage_enable = True], but you didn't set [no_engines_listening_address_list]."
298
+ raise SocketWrapperConfigurationValuesError(message)
299
+ elif not self.no_engine_usage_enable and not self.engines_list:
300
+ message = "You set [no_engine_usage_enable = False], but you didn't set [engines_list]."
301
+ raise SocketWrapperConfigurationValuesError(message)
302
+
278
303
  try:
279
304
  booleans.is_only_1_true_in_list(
280
305
  booleans_list_of_tuples=[
@@ -322,7 +347,16 @@ class SocketWrapper:
322
347
  print_api(message, color='red', logger=self.logger)
323
348
  return 1
324
349
 
325
- port_in_use = networks.get_processes_using_port_list(self.listening_address_list)
350
+ # Checking if listening address is in use.
351
+ listening_check_list: list = list()
352
+ if self.engines_list:
353
+ for engine in self.engines_list:
354
+ for address in engine.tcp_listening_address_list:
355
+ if address not in listening_check_list:
356
+ listening_check_list.append(address)
357
+ else:
358
+ listening_check_list = self.no_engines_listening_address_list
359
+ port_in_use = networks.get_processes_using_port_list(listening_check_list)
326
360
  if port_in_use:
327
361
  error_messages: list = list()
328
362
  for port, process_info in port_in_use.items():
@@ -399,26 +433,74 @@ class SocketWrapper:
399
433
 
400
434
  return self.socket_object
401
435
 
402
- def create_tcp_listening_socket_list(self, overwrite_list: bool = False):
403
- # If 'overwrite_list' was set to 'True', we will create new list. The default is 'False', since it is meant to`
404
- # add new sockets to already existing ones.
405
- if overwrite_list:
406
- self.listening_sockets = list()
407
-
408
- # Creating a socket for each port in the list set in configuration file
409
- for address in self.listening_address_list:
410
- ip_address, port_str = address.split(':')
411
- port = int(port_str)
412
- socket_by_port = self.create_socket_ipv4_tcp(
413
- ip_address, port)
414
-
415
- self.listening_sockets.append(socket_by_port)
436
+ def start_listening_sockets(
437
+ self,
438
+ reference_function_name,
439
+ reference_function_args=(),
440
+ pass_function_reference_to_thread: bool = True
441
+ ):
442
+ """
443
+ Start listening sockets with parameters.
444
+ """
416
445
 
417
- def loop_for_incoming_sockets(
446
+ # If engines were passed, we will use the listening addresses from the engines.
447
+ if not self.no_engine_usage_enable:
448
+ for engine in self.engines_list:
449
+ # Start all the regular listening interfaces.
450
+ for address in engine.tcp_listening_address_list:
451
+ ip_address, port_str = address.split(':')
452
+ port = int(port_str)
453
+ socket_by_port = self.create_socket_ipv4_tcp(ip_address, port)
454
+ threading.Thread(
455
+ target=self.listening_socket_loop,
456
+ args=(socket_by_port, engine, reference_function_name,
457
+ reference_function_args, pass_function_reference_to_thread),
458
+ name=f"acceptor-{engine.engine_name}-{ip_address}:{port}",
459
+ daemon=True
460
+ ).start()
461
+
462
+ # Start all the interfaces configured in the no_sni section.
463
+ if engine.no_sni.serve_domain_on_address_enable:
464
+ for domain, ip_port_address in engine.no_sni.serve_domain_on_address_dict.items():
465
+ ip_address, port_str = ip_port_address.split(':')
466
+ port = int(port_str)
467
+ socket_by_port = self.create_socket_ipv4_tcp(ip_address, port)
468
+ threading.Thread(
469
+ target=self.listening_socket_loop,
470
+ args=(socket_by_port, engine, reference_function_name,
471
+ reference_function_args, pass_function_reference_to_thread),
472
+ name=f"acceptor-{engine.engine_name}-{ip_address}:{port}",
473
+ daemon=True
474
+ ).start()
475
+ else:
476
+ # If no engines were passed, we will use the listening addresses from the configuration.
477
+ for address in self.no_engines_listening_address_list:
478
+ ip_address, port_str = address.split(':')
479
+ port = int(port_str)
480
+ socket_by_port = self.create_socket_ipv4_tcp(ip_address, port)
481
+ threading.Thread(
482
+ target=self.listening_socket_loop,
483
+ args=(socket_by_port, None, reference_function_name,
484
+ reference_function_args, pass_function_reference_to_thread),
485
+ name=f"acceptor-{ip_address}:{port}",
486
+ daemon=True
487
+ ).start()
488
+
489
+ # # Creating a socket for each port in the list set in configuration file
490
+ # for address in self.listening_address_list:
491
+ # ip_address, port_str = address.split(':')
492
+ # port = int(port_str)
493
+ # socket_by_port = self.create_socket_ipv4_tcp(
494
+ # ip_address, port)
495
+ #
496
+ # self.listening_sockets.append(socket_by_port)
497
+
498
+ def listening_socket_loop(
418
499
  self,
500
+ listening_socket_object: socket.socket,
501
+ engine: initialize_engines.ModuleCategory,
419
502
  reference_function_name,
420
503
  reference_function_args=(),
421
- listening_socket_list: list = None,
422
504
  pass_function_reference_to_thread: bool = True
423
505
  ):
424
506
  """
@@ -426,6 +508,8 @@ class SocketWrapper:
426
508
  The boolean variable was declared True in the beginning of the script and will be set to False if the process
427
509
  will be killed or closed.
428
510
 
511
+ :param listening_socket_object: listening socket that was created with bind.
512
+ :param engine: ModuleCategory.
429
513
  :param reference_function_name: callable, function reference that you want to execute when client
430
514
  socket received by 'accept()' and connection has been made.
431
515
  :param reference_function_args: tuple, that will be passed to 'function_reference' when it will be called.
@@ -439,17 +523,13 @@ class SocketWrapper:
439
523
  process_name: string, process name that was gathered from the socket.
440
524
  is_tls: boolean, if the socket is SSL/TLS.
441
525
  domain_from_dns_server: string, domain that was requested from DNS server.
442
- :param listening_socket_list: list, of sockets that you want to listen on.
443
526
  :param pass_function_reference_to_thread: boolean, that sets if 'function_reference' will be
444
527
  executed as is, or passed to thread. 'function_reference' can include passing to a thread,
445
528
  but you don't have to use it, since SocketWrapper can do it for you.
446
529
  :return:
447
530
  """
448
531
 
449
- # If 'listening_socket_list' wasn't specified and 'self.listening_sockets' is not empty.
450
- if not listening_socket_list and self.listening_sockets:
451
- # Then assign 'self.listening_sockets'.
452
- listening_socket_list = self.listening_sockets
532
+ listening_sockets: list = [listening_socket_object]
453
533
 
454
534
  while True:
455
535
  try:
@@ -457,7 +537,7 @@ class SocketWrapper:
457
537
  # operating system types: Windows / Linux / BSD.
458
538
  # To accept connection, we don't need "writable" and "exceptional", since "readable" holds the currently
459
539
  # connected socket.
460
- readable, writable, exceptional = select.select(listening_socket_list, [], [])
540
+ readable, writable, exceptional = select.select(listening_sockets, [], [])
461
541
  listening_socket_object = readable[0]
462
542
 
463
543
  # Get the domain queue. Tried using "Queue.Queue" object, but it stomped the SSL Sockets
@@ -465,11 +545,21 @@ class SocketWrapper:
465
545
  domain_from_dns_server = None
466
546
  if self.request_domain_from_dns_server_queue is not None:
467
547
  # domain_from_dns_server = self.request_domain_from_dns_server_queue.get()
468
- import queue
469
- try:
470
- domain_from_dns_server = self.request_domain_from_dns_server_queue.get_nowait()
471
- except queue.Empty:
472
- domain_from_dns_server = self.engine_no_sni_domain
548
+ if engine.no_sni.get_from_dns:
549
+ domain_from_dns_server = self.request_domain_from_dns_server_queue.get()
550
+
551
+ if engine.no_sni.serve_domain_on_address_enable:
552
+ # try:
553
+ # domain_from_dns_server = self.request_domain_from_dns_server_queue.get_nowait()
554
+ # except queue.Empty:
555
+ # domain_from_dns_server = engine.no_sni['domain']
556
+
557
+ listening_ip, listening_port = listening_socket_object.getsockname()
558
+ for domain, ip_port_address in engine.no_sni.serve_domain_on_address_dict.items():
559
+ ip_address: str = ip_port_address.split(':')[0]
560
+ if ip_address == listening_ip:
561
+ domain_from_dns_server = domain
562
+ break
473
563
 
474
564
  self.logger.info(f"Requested domain from DNS Server: {domain_from_dns_server}")
475
565
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.20.8
3
+ Version: 2.21.1
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License