From 713d3a6a392db2f7b2c368b09a65254d8b1a8d00 Mon Sep 17 00:00:00 2001 From: "Tristan B. Kildaire" Date: Sun, 26 Dec 2021 11:57:17 +0200 Subject: [PATCH] Working on connection handler sub-system --- source/dnetd/connection/connection.d | 52 ++++++++++++++++++++++ source/dnetd/listeners.d | 13 ------ source/dnetd/listeners/listeners.d | 42 ++++++++++++++++++ source/dnetd/listeners/socket.d | 65 ++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 13 deletions(-) create mode 100644 source/dnetd/connection/connection.d delete mode 100644 source/dnetd/listeners.d create mode 100644 source/dnetd/listeners/listeners.d create mode 100644 source/dnetd/listeners/socket.d diff --git a/source/dnetd/connection/connection.d b/source/dnetd/connection/connection.d new file mode 100644 index 0000000..9974951 --- /dev/null +++ b/source/dnetd/connection/connection.d @@ -0,0 +1,52 @@ +/** +* +*/ +module dnetd.connection.connection; + +import core.thread : Thread; + +/** +* Represents a client's/server's connection to +* this server +* +* These are normally spawned by the `serviceLoop` +* of Listener sub-classes +*/ +public abstract class Connection : Thread +{ + this() + { + super(&handler); + } + + /** + * Connection handler + * + * This is to be implemented by sub-classes + */ + public abstract void handler(); +} + + +import std.socket; +/** +* FIXME: When we do anything so far, I am assuming +* a streaming socket so we shouldn't let the +* SocketListener use any SocketType that isn't STREAM +*/ +public final class SocketConnection : Connection +{ + private Socket clientSock; + + this(Socket socket) + { + clientSock = socket; + } + + public override void handler() + { + while(true) + { + } + } +} diff --git a/source/dnetd/listeners.d b/source/dnetd/listeners.d deleted file mode 100644 index 0abbe43..0000000 --- a/source/dnetd/listeners.d +++ /dev/null @@ -1,13 +0,0 @@ -/** -* Module for listeners -* -* These include the base listener class responsible -* for managing a connection with peers and some -* concrete classes implementing this for various -* network protocols -*/ -module dnetd.listeners; - -public abstract class Listener -{ -} diff --git a/source/dnetd/listeners/listeners.d b/source/dnetd/listeners/listeners.d new file mode 100644 index 0000000..49a0367 --- /dev/null +++ b/source/dnetd/listeners/listeners.d @@ -0,0 +1,42 @@ +/** +* Module for listeners +* +* These include the base listener class responsible +* for managing a connection with peers and some +* concrete classes implementing this for various +* network protocols +*/ +module dnetd.listeners.listeners; + +import dnetd.server : Server; +import dnetd.exceptions : GeneralException; +import std.exception; +import core.thread : Thread; + +public abstract class Listener : Thread +{ + private Server server; + + this(Server server) + { + super(&serviceLoop); + this.server = server; + } + + /** + * The connection accepting loop of which + * is provided as the "worker" function to + * the thread + */ + public abstract void serviceLoop(); +} + +public abstract class ListenerException : GeneralException +{ + /* TODO: Potentially remove `listener` */ + this(Listener listener, string msg) + { + /* TODO: Set message here */ + super(msg); + } +} diff --git a/source/dnetd/listeners/socket.d b/source/dnetd/listeners/socket.d new file mode 100644 index 0000000..de8403a --- /dev/null +++ b/source/dnetd/listeners/socket.d @@ -0,0 +1,65 @@ +/** +* Socket-based listener for supporting any +* network protocol that Linux supports, such as +* TCP (STREAM-based) on IPv4 and IPv6 and UNIX +* domain sockets... to name a few. +*/ +module dnetd.listeners.socket; + +import dnetd.listeners.listeners; +import dnetd.server : Server; +import std.socket; +import std.conv : to; + +public final class SocketListenerException : ListenerException +{ + this(SocketListener e) + { + string msg = to!(string)(e.getAddress().addressFamily) + ~ + "-type socket listener error"; + + super(e, msg); + } +} + +public final class SocketListener : Listener +{ + private Socket socket; + private Address address; + + this(Server server, Address address, SocketType type, ProtocolType proto) + { + super(server); + this.address = address; + + try + { + socket = new Socket(address.addressFamily, type, proto); + socket.bind(address); + } + catch(SocketOSException e) + { + throw new SocketListenerException(this); + } + } + + /** + * Socket accept-and-connection spawner + * loop + */ + public override void serviceLoop() + { + while(true) + { + Socket clientSock = socket.accept(); + + //TODO + } + } + + public Address getAddress() + { + return address; + } +}