54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
import socket
|
|
import threading
|
|
import logging
|
|
|
|
from core.peer import BankPeer
|
|
|
|
|
|
class BankScanner(threading.Thread):
|
|
def __init__(self, host: str, port: str, result_peer: BankPeer, bank_found_event: threading.Event, lock: threading.Lock, timeout: int):
|
|
super().__init__(name="BankScannerThread-{self.host}:{port}")
|
|
self.logger = logging.getLogger(__name__)
|
|
self.host = host
|
|
self.port = port
|
|
self.result_peer = result_peer
|
|
self.bank_found_event = bank_found_event
|
|
self.lock = lock
|
|
self.timeout = timeout
|
|
|
|
def run(self):
|
|
if self.bank_found_event.is_set():
|
|
return
|
|
|
|
self.__probe_for_open_ports(self.host, self.port)
|
|
|
|
def __probe_for_open_ports(self, host: str, port: int):
|
|
try:
|
|
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
connection.settimeout(self.timeout)
|
|
connection.connect((host, port))
|
|
self.__scan_for_bank(connection)
|
|
except socket.timeout:
|
|
self.logger.debug("Connection for port %d timed out", port)
|
|
except socket.error as e:
|
|
if e.errno == 111: # Connection refused
|
|
self.logger.debug("Port %d not open", port)
|
|
else:
|
|
self.logger.debug("Unknown error occurred when probing port: %s", e)
|
|
|
|
def __scan_for_bank(self, connection: socket.socket):
|
|
ping_command = "BC"
|
|
connection.sendall(ping_command.encode("utf-8"))
|
|
response = connection.recv(1024).decode("utf-8")
|
|
|
|
if response.strip() == f"BC {self.host}":
|
|
self.logger.debug("Bank application found on %s:%s", self.host, self.port)
|
|
|
|
with self.lock:
|
|
if not self.bank_found_event.is_set():
|
|
self.result_peer.port = self.port
|
|
self.result_peer.bank_socket = connection
|
|
self.bank_found_event.set()
|
|
else:
|
|
self.logger.debug("Port is open, but no bank application found")
|