1
0
mirror of https://github.com/deavminet/dnetd synced 2024-09-21 17:53:39 +02:00
dnetd_old/source/dnetd/dlink.d

310 lines
6.7 KiB
D
Raw Normal View History

2020-10-05 15:59:08 +02:00
module dnetd.dlink;
import dnetd.dconnection;
import core.sync.mutex : Mutex;
import std.stdio;
import std.conv;
import dnetd.dserver;
2021-01-28 23:43:22 +02:00
import dnetd.dconfig;
2021-01-29 14:28:52 +02:00
import std.socket : Address;
import core.thread : Thread;
2021-01-30 11:50:11 +02:00
import std.socket;
import gogga;
import core.thread;
import tristanable.encoding : DataMessage;
import bmessage : bSendMessage = sendMessage, bReceiveMessage = receiveMessage;
2021-01-30 14:17:01 +02:00
import std.string : cmp;
2020-10-05 15:59:08 +02:00
2021-01-29 19:49:39 +02:00
/**
* Link manager
*
* Given a set of original DLink objects, it will open connections to them
* It also facilitates DConnection making a call to `.addLink` here when an
* inbound peering request comes in
*/
public final class DLinkManager
{
2021-01-29 20:48:18 +02:00
this(DServer server)
2021-01-29 19:49:39 +02:00
{
}
2021-01-29 20:48:18 +02:00
/**
* Goes through the DConnection[] array in DServer and returns
* all connections that are SERVER connections
*/
public DConnection[] getLinkedServers()
{
DConnection[] links;
/* TODO: Implement me */
return links;
}
2021-01-29 19:49:39 +02:00
}
2021-01-29 14:28:52 +02:00
/**
* Represents a server link
*
* Either used for inbound or outbound
*/
public final class DLink : Thread
{
/* Associated server */
private DServer server;
/* The connection */
private DConnection connection;
/**
* Links details
*/
private string name;
private Address address;
2021-01-30 11:50:11 +02:00
/**
* Outbound utilities
*/
private Socket outboundSocket;
2021-01-29 14:28:52 +02:00
/**
* Constructs a DLink for an outbound peering
*/
this(DServer server, string name, Address address)
{
/* Set the worker thread for outbound connections */
super(&outboundWorker);
2021-01-29 15:04:08 +02:00
2021-01-30 12:50:44 +02:00
this.server = server;
2021-01-29 20:48:18 +02:00
this.name = name;
this.address = address;
2021-01-29 14:28:52 +02:00
/* Create an outbound connection */
/* TODO: Fuuuuuuuuuuuuuuuuuuuck handling of shit here bababooey and not in dconnection.d as we would have done below */
2021-01-29 14:28:52 +02:00
}
/**
* Initializes a new outbound connection
*/
private void initializeOutboundConnection()
{
/* Open a connection to the server */
2021-01-30 11:50:11 +02:00
outboundSocket = new Socket(address.addressFamily, SocketType.STREAM, ProtocolType.TCP);
gprintln(address);
while(true)
{
try
{
2021-01-30 11:50:11 +02:00
outboundSocket.connect(address);
break;
}
catch(SocketOSException)
{
gprintln("Could not link with server "~name~"!", DebugType.ERROR);
Thread.sleep(dur!("seconds")(3));
}
}
2021-01-29 20:48:18 +02:00
2021-01-29 14:28:52 +02:00
}
private void outboundWorker()
{
/* Initialize a new outbound connection */
initializeOutboundConnection();
bool status = linkHandshake();
/* TODO: Implement me */
while(true)
{
}
}
/**
* Performs the server LINK command and makes sure
* the server accepts the linking and also that the
* links name on our local server match up
*/
private bool linkHandshake()
{
bool status = true;
2021-01-30 11:39:58 +02:00
/* TODO: Send LINK (1) command */
byte[] data;
data ~= [1];
2021-01-30 12:50:44 +02:00
gprintln("Here", DebugType.WARNING);
2021-01-30 12:10:48 +02:00
/* TODO: Encode [serverNameLen, serverName] */
2021-01-30 12:25:40 +02:00
string serverName = server.getGeneralConfig().getName();
2021-01-30 12:10:48 +02:00
data ~= [cast(byte)serverName.length];
data ~= serverName;
2021-01-30 11:39:58 +02:00
2021-01-30 11:50:11 +02:00
/* Encode and send LINK command */
DataMessage message = new DataMessage(0, data);
bSendMessage(outboundSocket, message.encode());
/* TODO: Await an acknowledgement [status] */
byte[] receivedResponseBytes;
2021-01-30 12:56:41 +02:00
bool recvStatus = bReceiveMessage(outboundSocket, receivedResponseBytes);
gprintln("Recev status: "~to!(string)(recvStatus), DebugType.WARNING);
DataMessage receivedResponse = DataMessage.decode(receivedResponseBytes);
2021-01-30 11:39:58 +02:00
ubyte[] dataReply = cast(ubyte[])receivedResponse.getData();
2021-01-30 11:39:58 +02:00
/* TODO: 0 is good, 1 is bad */
if(dataReply[0] == 0)
2021-01-29 18:29:05 +02:00
{
/* TODO: Get server name, makes sure it matches on in config file */
2021-01-30 13:44:15 +02:00
ubyte nameLen = dataReply[1];
2021-01-30 13:41:25 +02:00
string name = cast(string)dataReply[2..2+nameLen];
gprintln("Server said his name is '"~name~"'", DebugType.WARNING);
2021-01-29 18:29:05 +02:00
2021-01-30 12:50:44 +02:00
2021-01-30 14:17:01 +02:00
/* Attempt to attach server */
status = server.getMeyer().attachLink(name, this);
gprintln("Outbound link status: "~to!(string)(status));
}
else if(dataReply[0] == 1)
{
/* TODO: Handle this case */
gprintln("Server linking rejected", DebugType.ERROR);
status = false;
}
else
{
/* TODO: Handle this case */
status = false;
2021-01-29 18:29:05 +02:00
}
/* TODO: If 0, then expect following [nameLen, name] */
return status;
}
2021-01-29 20:48:18 +02:00
override public string toString()
{
return "Server: "~name~", Address: "~to!(string)(address);
}
2021-01-29 14:28:52 +02:00
/**
* Constructs a DLink for an inbound peering
*/
this(DServer server, string name, Address address, DConnection connection)
{
2021-01-29 18:29:05 +02:00
/* Save the server, name and address */
/* Save the active connection */
2021-01-29 14:28:52 +02:00
/* Save name and address */
this(server, name, address);
/* Save connection */
}
2021-01-30 14:11:29 +02:00
public string getName()
{
return name;
}
2021-01-29 14:28:52 +02:00
}
2021-01-30 11:39:58 +02:00
/* TODO: Remove this from here and put it in DServer */
2020-10-05 15:59:08 +02:00
public final class DMeyer
{
2021-01-28 23:43:22 +02:00
/* Direct peers */
2021-01-30 13:41:25 +02:00
private DLink[] links;
2020-10-05 15:59:08 +02:00
private Mutex linksMutex;
2021-01-28 23:43:22 +02:00
/* Associated server */
2020-10-05 15:59:08 +02:00
private DServer server;
2021-01-30 13:41:25 +02:00
this(DServer server, DLink[] links)
2020-10-05 15:59:08 +02:00
{
this.server = server;
/* Initialize the locks */
initLocks();
2021-01-29 14:28:52 +02:00
/* Open a connection to the server */
/* TODO: Open connections to all servers we are yet to open a connection to (check the `links` array) */
2021-01-30 14:27:31 +02:00
//this.links = links;
}
2021-01-29 19:49:39 +02:00
/* Initialize locks */
private void initLocks()
{
2020-10-05 15:59:08 +02:00
linksMutex = new Mutex();
}
2021-01-30 14:11:29 +02:00
public bool attachLink(string serverName, DLink link)
{
/* Link exists? */
bool linkGood = true;
/* Lock the links list */
linksMutex.lock();
/* Search for this entry, only add it if it doens't exist */
2021-01-30 14:17:01 +02:00
foreach(DLink currentLink; links)
2021-01-30 14:11:29 +02:00
{
2021-01-30 14:17:01 +02:00
if(cmp(currentLink.getName(), serverName) == 0)
2021-01-30 14:11:29 +02:00
{
linkGood = false;
break;
}
}
2021-01-30 14:23:47 +02:00
if(linkGood)
{
links ~= link;
}
2021-01-30 14:11:29 +02:00
/* Unlock the links list */
linksMutex.unlock();
return linkGood;
}
2021-01-30 13:41:25 +02:00
public DLink[] getLinks()
2021-01-29 19:49:39 +02:00
{
2021-01-30 13:41:25 +02:00
return links;
2021-01-29 19:49:39 +02:00
}
2020-10-05 15:59:08 +02:00
}
2021-01-30 11:39:58 +02:00
/**
* Initializes a new inbound connection that is to be used for linking
*/
void initializeLink(DServer server, DConnection newConnection)
{
}