public static void Initialise(int initialPort, bool rangeRandomPortFailover = true)
{
try
{
if (initialPort > MaxTargetLocalPort || initialPort < MinTargetLocalPort)
throw new CommsSetupShutdownException("Provided initial DFS port must be within the MinTargetLocalPort and MaxTargetLocalPort range.");
if (Connection.AllExistingLocalListenEndPoints().Count > 0)
throw new CommsSetupShutdownException("Unable to initialise DFS if already listening for incoming connections.");
DFSShutdownEvent = new ManualResetEvent(false);
elapsedTimerThread = new Thread(ElapsedTimerWorker);
elapsedTimerThread.Name = "DFSElapsedTimerThread";
elapsedTimerThread.IsBackground = true;
elapsedTimerThread.Start();
//Load the allowed IP addresses
LoadAllowedDisallowedPeerIPs();
NetworkComms.IgnoreUnknownPacketTypes = true;
#region Add Packet Handlers
//TCP
NetworkComms.AppendGlobalIncomingPacketHandler<ItemAssemblyConfig>("DFS_IncomingLocalItemBuild", IncomingLocalItemBuild);
NetworkComms.AppendGlobalIncomingPacketHandler<string[]>("DFS_RequestLocalItemBuild", RequestLocalItemBuilds);
//UDP
//DO NOT MAKE THIS METHOD USE highPriority. If this method blocks it prevents other data coming in
NetworkComms.AppendGlobalIncomingPacketHandler<ChunkAvailabilityRequest>("DFS_ChunkAvailabilityInterestRequest", IncomingChunkInterestRequest);
NetworkComms.AppendGlobalIncomingPacketHandler<byte[]>("DFS_ChunkAvailabilityInterestReplyData", IncomingChunkInterestReplyData);
//UDP & TCP
NetworkComms.AppendGlobalIncomingPacketHandler<ChunkAvailabilityReply>("DFS_ChunkAvailabilityInterestReplyInfo", IncomingChunkInterestReplyInfo);
//UDP
NetworkComms.AppendGlobalIncomingPacketHandler<string>("DFS_ChunkAvailabilityRequest", IncomingChunkAvailabilityRequest, highPrioReceiveSRO);
//UDP
NetworkComms.AppendGlobalIncomingPacketHandler<PeerChunkAvailabilityUpdate>("DFS_PeerChunkAvailabilityUpdate", IncomingPeerChunkAvailabilityUpdate, highPrioReceiveSRO);
//UDP
NetworkComms.AppendGlobalIncomingPacketHandler<ItemRemovalUpdate>("DFS_ItemRemovalUpdate", IncomingItemRemovalUpdate, highPrioReceiveSRO);
//UDP
NetworkComms.AppendGlobalIncomingPacketHandler<KnownPeerEndPoints>("DFS_KnownPeersUpdate", KnownPeersUpdate, highPrioReceiveSRO);
NetworkComms.AppendGlobalIncomingPacketHandler<string>("DFS_KnownPeersRequest", KnownPeersRequest, highPrioReceiveSRO);
//TCP
NetworkComms.AppendGlobalIncomingPacketHandler<DFSLinkRequest>("DFS_ItemLinkRequest", IncomingRemoteItemLinkRequest);
NetworkComms.AppendGlobalConnectionCloseHandler(DFSConnectionShutdown);
#endregion
if (DFS.loggingEnabled)
{
DFS.Logger.Info("Starting DFS listeners.");
DFS.Logger.Info("Comms IP filters - " + HostInfo.IP.RestrictLocalAddressRanges.Select((range) => range.ToString()).Aggregate((left,right) => left.ToString() + ", " + right.ToString()).ToString());
DFS.Logger.Info("Detected addresses - " + HostInfo.IP.FilteredLocalAddresses().Select((address) => address.ToString()).Aggregate((left, right) => left.ToString() + ", " + right.ToString()).ToString());
}
#region OpenIncomingPorts
try
{
Connection.StartListening(ConnectionType.TCP, new IPEndPoint(IPAddress.Any, initialPort));
Connection.StartListening(ConnectionType.UDP, new IPEndPoint(IPAddress.Any, initialPort));
}
catch (Exception)
{
//If an exception occurred first reset NetworkComms.Net
NetworkComms.Shutdown();
if (rangeRandomPortFailover)
{
//Keep trying to listen on an ever increasing port number
for (int tryPort = MinTargetLocalPort; tryPort <= MaxTargetLocalPort; tryPort++)
{
try
{
Connection.StartListening(ConnectionType.TCP, new IPEndPoint(IPAddress.Any, tryPort));
Connection.StartListening(ConnectionType.UDP, new IPEndPoint(IPAddress.Any, tryPort));
//Once we are successfully listening we can break
break;
}
catch (Exception) { NetworkComms.Shutdown(); }
if (tryPort == MaxTargetLocalPort)
throw new CommsSetupShutdownException("Failed to find local available listen port while trying to initialise DFS.");
}
}
else
throw;
}
//Do some validation
if (Connection.ExistingLocalListenEndPoints(ConnectionType.TCP).Except(Connection.ExistingLocalListenEndPoints(ConnectionType.UDP)).Count() > 0)
throw new CommsSetupShutdownException("Port mismatch when comparing TCP and UDP local listen end points.");
if ((from current in Connection.ExistingLocalListenEndPoints(ConnectionType.TCP)
where ((IPEndPoint)current).Port > MaxTargetLocalPort || ((IPEndPoint)current).Port < MinTargetLocalPort
select current).Count() > 0)
throw new CommsSetupShutdownException("Local port selected that is not within the valid range.");
#endregion
if (DFS.loggingEnabled) DFS._DFSLogger.Info("Initialised DFS");
}
catch (Exception e)
{
LogTools.LogException(e, "Error_DFSIntialise");
}
DFSInitialised = true;
}