Implement support for IPv6 listener

Implement support for IPv6 listener via Python selectors module to
monitor multiple listening sockets
This commit is contained in:
XANTRONIX Development 2024-12-03 23:38:45 -05:00
parent 6944f3f898
commit 32281a3aa2

View file

@ -1,10 +1,12 @@
import enum
import socket
import ssl
import threading
import socket
import selectors
import ssl
from configparser import ConfigParser
from nntp.tiny.config import ConfigException
from nntp.tiny.db import Database
from nntp.tiny.newsgroup import Newsgroup
from nntp.tiny.session import Session
@ -37,28 +39,52 @@ class Server():
for newsgroup in db.query(Newsgroup).each():
self.newsgroups[newsgroup.name.casefold()] = newsgroup
def run(self):
host = self.config['listen']['host']
port = int(self.config['listen']['port'])
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def listen(self, host: str, port: int, af: int):
listener = socket.socket(af, socket.SOCK_STREAM)
listener.bind((host, port))
listener.listen()
if self.sslctx:
listener = self.sslctx.wrap_socket(listener, server_side=True)
return self.sslctx.wrap_socket(listener, server_side=True)
return listener
def accept(self, listener):
try:
sock, addr = listener.accept()
def spawn():
session = Session(self, sock)
session.handle()
thread = threading.Thread(target=spawn)
thread.start()
except ssl.SSLEOFError as e:
pass
def run(self):
port = int(self.config['listen']['port'])
listeners = list()
if self.config.has_option('listen', 'host_inet'):
host = self.config.get('listen', 'host_inet')
listeners.append(self.listen(host, port, socket.AF_INET))
if self.config.has_option('listen', 'host_inet6'):
host = self.config.get('listen', 'host_inet6')
listeners.append(self.listen(host, port, socket.AF_INET6))
if len(listeners) == 0:
raise ConfigException("No listener hosts specified")
sel = selectors.DefaultSelector()
for listener in listeners:
sel.register(listener, selectors.EVENT_READ)
while True:
try:
sock, addr = listener.accept()
events = sel.select()
def spawn():
session = Session(self, sock)
session.handle()
thread = threading.Thread(target=spawn)
thread.start()
except ssl.SSLEOFError as e:
pass
listener.close()
for key, ev in events:
self.accept(key.fileobj)