Implement support for IPv6 listener
Implement support for IPv6 listener via Python selectors module to monitor multiple listening sockets
This commit is contained in:
parent
6944f3f898
commit
32281a3aa2
1 changed files with 46 additions and 20 deletions
|
@ -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()
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue