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 enum
import socket
import ssl
import threading import threading
import socket
import selectors
import ssl
from configparser import ConfigParser from configparser import ConfigParser
from nntp.tiny.config import ConfigException
from nntp.tiny.db import Database from nntp.tiny.db import Database
from nntp.tiny.newsgroup import Newsgroup from nntp.tiny.newsgroup import Newsgroup
from nntp.tiny.session import Session from nntp.tiny.session import Session
@ -37,28 +39,52 @@ class Server():
for newsgroup in db.query(Newsgroup).each(): for newsgroup in db.query(Newsgroup).each():
self.newsgroups[newsgroup.name.casefold()] = newsgroup self.newsgroups[newsgroup.name.casefold()] = newsgroup
def run(self): def listen(self, host: str, port: int, af: int):
host = self.config['listen']['host'] listener = socket.socket(af, socket.SOCK_STREAM)
port = int(self.config['listen']['port'])
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind((host, port)) listener.bind((host, port))
listener.listen() listener.listen()
if self.sslctx: 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: while True:
try: events = sel.select()
sock, addr = listener.accept()
def spawn(): for key, ev in events:
session = Session(self, sock) self.accept(key.fileobj)
session.handle()
thread = threading.Thread(target=spawn)
thread.start()
except ssl.SSLEOFError as e:
pass
listener.close()