v1.1.5
Against all odds, I have just sent off v1.1.5 so it should become available on Monday.
I have not yet completed a NAT punch-through demo, but it should be possible with the current version.
Moving from v1.1.4 to v1.1.5
This is relatively straightforward. By default, everything is the same as it was in v1.1.4 e.g. graceful disconnect is disabled.
You only have to worry about the following:
-mnGetTCPRecvSize has been renamed mnGetTCPRecvSizeA.
-mnGetErrorCode now returns long long int instead of int.
-mnGetErrorMode now takes an error mode parameter and is used to determine whether an error mode is on or off.
-mnConnect and mnPollConnect can now return -2 indicating that the server rejected the connection request. This normally means the server is full.
-mnSetFunction, the thread ID of function parameters is no longer passed by reference.
General
DarkNet has been optimised and restructured. There isn't much that hasn't improved in efficiency, so hopefully you will notice some kind of performance increase.
The
help files have been completely rewritten and are much more useful and easy to use.
There is now alot of new demo code. There are now 19 projects demonstrating various aspects of DarkNet.
There are also several bugs that have been fixed:
- Packet commands may not always display correct error message when there is not enough memory in packet to add or get data.
- Packets may not always have variables such as client ID set properly.
- Server/clients could not continue to transfer data in UDP mode 2 and 1 after 49.7 days of being connected.
- Vulnerability where certain situations could cause the server to display an error message or be unable to receive UDP data.
- mnFinish would not re-enable UDP on the specified instance.
- mnToggleAffinity, mnGetAffinity, mnSetAffinity, mnGetPriority and mnSetPriority were not working.
Improved Error System
You can now have more than one error mode enabled at the same time using mnToggleErrorMode. mnGetErrorMode has changed as a result.
Save error mode has improved so that you don't have to check the return values of commands to determine if an error has occurred. Instead you can use mnGetErrorFlag to determine when an error has occurred. You can use mnSetErrorFlag and mnClearErrorFlag to toggle error state and control what mnGetErrorFlag returns.
A clError (C++) and mnError (.NET) exception class now exists. When exception error mode (new) is enabled DarkNet functions will throw an exception of this type when an error occurs. The exception class is used internally to DarkNet; you now have the option to integrate your applications with the same error system that DarkNet uses. The documentation explains how to do this.
mnGetErrorMode now takes an error mode parameter and is used to determine whether an error mode is on or off.
There is demo code showing how to use the new error system.
Command list:
bool mnGetErrorFlag();
void mnSetErrorFlag();
void mnClearErrorFlag();
int mnToggleErrorMode(int Mode);
int mnGetErrorMode(int Mode);
struct clError
{
bool bGenerated; // Indicates whether object is completely filled with info about an error
char * sFullMessage;
const char * sOperation;
const char * sCommand;
long long int iErrorCode; // Large data type to ensure compatibility with all possible return types (e.g. including UINT)
int iLine;
const char * sFile;
// Helper functions
void _CheckGenerated(); // Error if bGenerated is not true
void _Copy(const clError & CopyMe); // Fills object with contents of CopyMe
void _DefaultVars(); // Sets variables to default
// Constructor, copy constructors and destructor
clError();
clError(const clError & CopyMe);
clError & operator= (const clError & CopyMe);
~clError();
// Manipulate variables
void Clear(); // Reset variables
void SetCore(const char * Operation, long long int ErrorCode, int LineNo, const char * CodeFile); // Set everything except command
void SetCommand(const char * Command); // Set command
void SetFull(const char * Command, const char * Operation, long long int ErrorCode, int LineNo, const char * CodeFile); // Set everything
// Generate full message based on information set by SetCore, SetCommand and SetFull
void Generate();
// Generate message and display message box
void GenMessageBox(const char * Command);
void GenMessageBox(const char * Command, const char * Operation, long long int ErrorCode, int LineNo, const char * CodeFile);
// Generate message and decide what to do based on error mode
void GenEvent(const char * Command);
void GenEvent(const char * Command, const char * Operation, long long int ErrorCode, int LineNo, const char * CodeFile);
// Generate message and throw exception
void GenRethrow(const char * Command);
void GenRethrow(const char * Command, const char * Operation, long long int ErrorCode, int LineNo, const char * CodeFile);
// Below must be used AFTER full message is generated
void DoMessageBox(); // Display message box
void DoSave(); // Save message to be returned by mnGetError commands
void DoRethrow(); // Throw clError exception
void DoEvent(); // Decides what action to take based on error mode
};
Packet Commands
Several new commands exist which make DarkNet packets more useful and dynamic.
mnErase can be used to erase a portion of the packet whilst mnInsert can be used to insert space into the packet, which can then be filled with an mnAdd command (e.g. mnAddInt).
A new command mnCreatePacketFromPacket exists which is faster than mnCreatePacket + mnEqualPacket. It has the same result as using those two commands.
There are several new string commands which operate similarly to their packet counterpart: mnCreatePacketFromString, mnComparePacketString, mnEqualPacketString.
mnChangeMemorySize can be used to change the memory size of a packet without wiping its contents (mnSetMemorySize wipes the contents of the packet).
mnAddMemblock and mnGetMemblock have been added for DBP users so that memblocks can be used with packets.
Command list:
int mnErase(long long int Packet, unsigned int StartPos, unsigned int Amount);
int mnInsert(long long int Packet, unsigned int Amount);
long long int mnCreatePacketFromPacket(long long int FromPacket);
long long int mnCreatePacketFromString(char * String);
int mnComparePacketString(long long int Packet, char * String);
int mnChangeMemorySize(long long int Packet, unsigned int Size);
int mnEqualPacketString(long long int Destination, char * From);
Networking Commands
Several new networking commands have been added.
mnFlushRecvUDP and mnFlushRecvTCP can be used to empty the packet queue whilst mnGetTCPStoreAmount and mnGetUDPStoreAmount can be used to determine the number of packets in the queue. Note: packet queue refers to the queue of packets waiting to be received via mnRecvUDP or mnRecvTCP.
mnChangeBufferSizeTCP can be used to change the maximum possible size of an incoming TCP packet whilst the instance is active. This operates on a per client basis. mnGetTCPRecvSizeB exists to retrieve buffer sizes on a per client basis.
mnSetAutoResizeTCP can be used to set no limit on the maximum possible size of incoming TCP packet. The buffer size will increase as necessary. This operates on a per client basis.
mnGetTCPBytes is similar to mnGetTCPPercent except it retrieves the number of bytes worth of partial data (data that does not make up a complete packet).
mnDisableTCPHandshake can be used to disable the TCP handshake process. When this process is disabled DarkNet can communicate with applications not written with DarkNet. mnGetTCPHandshakeEnabled exists to check whether TCP handshake has been disabled.
mnSetTCPMode can be used to change the TCP mode to the new postfix mode which adds specified bytes of data to the end of each packet, and checks for these bytes at the end of incoming data to determine when a complete packet has been received. mnGetTCPMode exists to determine the TCP mode.
mnSetTCPPostfix can be used to set the postfix used with the postfix TCP mode. mnGetTCPPostfix exists to determine what the postfix is.
mnSetTCPMode and mnDisableTCPHandshake make communication via HTTP possible. Demo code exists to demonstrate this.
Graceful disconnecting is now possible using mnShutdownClient, mnEnableGracefulDisconnect and mnGetGracefulDisconnectEnabled. This allows clients to disconnect but data transfer to complete successfully.
mnSetSendTimeout and mnGetSendTimeout exist to protect the server from malicious clients. After the send timeout expires, if a packet has not been sent the client is forcefully dropped. This prevents blocking send operations from blocking permanently.
There is a new UDP mode (4) UM_CATCH_ALL_NO, UDP mode catch all, no out of order which is used in exactly the same way as UDP mode catch all but out of order packets are discarded.
All UDP modes now have procedures to ensure that data transfer can continue forever. Previously UDP modes 1 (per client) and 2 (per client, per operation) would stop working if a client did not disconnect after roughly 49.7 days.
mnDisableNagle and mnGetNagleEnabled can be used to disable the Nagle Algorithm which may improve TCP performance for some applications.
mnConnect and mnPollConnect can now return -2 indicating that the server rejected the connection request. This normally means the server is full.
Command list:
nt mnFlushRecvTCP(int Instance, int Client);
int mnFlushRecvUDP(int Instance, int Client);
int mnChangeBufferSizeTCP(int Instance, int Client, unsigned int iSize);
int mnSetAutoResizeTCP(int Instance, int Client, bool bAutoResize);
unsigned int mnGetTCPRecvSizeB(int Instance, int Client);
unsigned int mnGetTCPBytes(int Instance, int Client);
int mnDisableTCPHandshake(int Instance);
int mnGetTCPHandshakeEnabled(int Instance);
char mnGetTCPMode(int Instance);
int mnSetTCPMode(int Instance, char iTCPMode);
int mnShutdownClient(int Instance, int Client);
int mnEnableGracefulDisconnect(int Instance);
int mnGetGracefulDisconnectEnabled(int Instance);
unsigned int mnGetSendTimeout(int Instance);
int mnSetSendTimeout(int Instance, unsigned int iTimeout);
unsigned int mnGetTCPStoreAmount(int Instance, int Client);
unsigned int mnGetUDPStoreAmount(int Instance, int Client);
int mnSetTCPPostfix(int Instance, long long int Packet);
int mnSetTCPPostfix(int Instance, clPacket & Packet);
int mnGetTCPPostfix(int Instance, long long int Packet);
int mnGetTCPPostfix(int Instance, clPacket & Packet);
int mnGetNagleEnabled(int Instance);
int mnDisableNagle(int Instance);
Firewall Commands
Roughly 90 new firewall commands have been added which allow full control over windows firewall.
Command list:
int mnStartFirewall();
int mnFinishFirewall();
int mnUpdateFirewall();
unsigned int mnGetCurrentProfile();
int mnResetFirewall();
int mnIsPortAllowedA(char * FileName, long PortNumber, int Protocol, char * LocalAddress, int IPVersion);
int mnIsPortAllowedB(long PortNumber, int Protocol);
int mnIsTypeAllowedICMPA(unsigned char Type, char * LocalAddress, int IPVersion);
int mnIsTypeAllowedICMPB(unsigned char Type, int IPVersion);
const char * mnGetServiceName(unsigned int ProfileID, unsigned int ServiceID);
int mnGetServiceType(unsigned int ProfileID, unsigned int ServiceID);
int mnGetServiceCustomized(unsigned int ProfileID, unsigned int ServiceID);
int mnGetServiceIPVersion(unsigned int ProfileID, unsigned int ServiceID);
int mnGetServiceScope(unsigned int ProfileID, unsigned int ServiceID);
const char * mnGetServiceRemoteAddresses(unsigned int ProfileID, unsigned int ServiceID);
int mnGetServiceEnabled(unsigned int ProfileID, unsigned int ServiceID);
int mnSetServiceIPVersion(unsigned int ProfileID, unsigned int ServiceID, int IPVersion);
int mnSetServiceScope(unsigned int ProfileID, unsigned int ServiceID, int Scope);
int mnSetServiceRemoteAddresses(unsigned int ProfileID, unsigned int ServiceID, char * RemoteAddresses);
int mnSetServiceEnabled(unsigned int ProfileID, unsigned int ServiceID, bool Enabled);
int mnAddServicePort(unsigned int ProfileID, unsigned int ServiceID, char * Name, int IPVersion, int Protocol, long PortNumber, int Scope, char * RemoteAddresses, bool Enabled);
int mnDeleteServicePortA(unsigned int ProfileID, unsigned int ServiceID, long PortNumber, int Protocol);
int mnDeleteServicePortB(unsigned int ProfileID, unsigned int ServiceID, unsigned int PortID);
unsigned int mnFindServicePort(unsigned int ProfileID, unsigned int ServiceID, long PortNumber, int Protocol);
int mnServicePortExist(unsigned int ProfileID, unsigned int ServiceID, long PortNumber, int Protocol);
unsigned int mnGetServicePortAmount(unsigned int ProfileID, unsigned int ServiceID);
int mnGetFirewallEnabled(unsigned int ProfileID);
int mnGetExceptionsAllowed(unsigned int ProfileID);
int mnGetNotificationsEnabled(unsigned int ProfileID);
int mnGetUnicastToMulticastEnabled(unsigned int ProfileID);
int mnGetRemoteAdminIPVersion(unsigned int ProfileID);
int mnGetRemoteAdminScope(unsigned int ProfileID);
const char * mnGetRemoteAdminAddresses(unsigned int ProfileID);
int mnGetRemoteAdminEnabled(unsigned int ProfileID);
int mnGetICMPAllowOutboundDestinationUnreachable(unsigned int ProfileID);
int mnGetICMPAllowRedirect(unsigned int ProfileID);
int mnGetICMPAllowInboundEchoRequest(unsigned int ProfileID);
int mnGetICMPAllowOutboundTimeExceeded(unsigned int ProfileID);
int mnGetICMPAllowOutboundParameterProblem(unsigned int ProfileID);
int mnGetICMPAllowOutboundSourceQuench(unsigned int ProfileID);
int mnGetICMPAllowInboundRouterRequest(unsigned int ProfileID);
int mnGetICMPAllowInboundTimestampRequest(unsigned int ProfileID);
int mnGetICMPAllowInboundMaskRequest(unsigned int ProfileID);
int mnGetICMPAllowOutboundPacketTooBig(unsigned int ProfileID);
int mnSetFirewallEnabled(unsigned int ProfileID, bool Boolean);
int mnSetExceptionsAllowed(unsigned int ProfileID, bool Boolean);
int mnSetNotificationsEnabled(unsigned int ProfileID, bool Boolean);
int mnSetUnicastToMulticastEnabled(unsigned int ProfileID, bool Boolean);
int mnSetRemoteAdminIPVersion(unsigned int ProfileID, int IPVersion);
int mnSetRemoteAdminScope(unsigned int ProfileID, int Scope);
int mnSetRemoteAdminAddresses(unsigned int ProfileID, char * Addresses);
int mnSetRemoteAdminEnabled(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowOutboundDestinationUnreachable(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowRedirect(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowInboundEchoRequest(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowOutboundTimeExceeded(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowOutboundParameterProblem(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowOutboundSourceQuench(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowInboundRouterRequest(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowInboundTimestampRequest(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowInboundMaskRequest(unsigned int ProfileID, bool Boolean);
int mnSetICMPAllowOutboundPacketTooBig(unsigned int ProfileID, bool Boolean);
unsigned int mnGetApplicationAmount(unsigned int ProfileID);
int mnAddApplication(unsigned int ProfileID, char * Name, char * FileName, int IPVersion, int Scope, char * RemoteAddresses, bool Enabled);
int mnDeleteApplicationA(unsigned int ProfileID, char * FileName);
int mnDeleteApplicationB(unsigned int ProfileID, unsigned int ApplicationID);
unsigned int mnFindApplication(unsigned int ProfileID, char * FileName);
int mnApplicationExist(unsigned int ProfileID, char * FileName);
unsigned int mnGetServiceAmount(unsigned int ProfileID);
int mnAddPort(unsigned int ProfileID, char * Name, int IPVersion, int Protocol, long PortNumber, int Scope, char * RemoteAddresses, bool Enabled);
int mnDeletePortA(unsigned int ProfileID, long PortNumber, int Protocol);
int mnDeletePortB(unsigned int ProfileID, unsigned int PortID);
unsigned int mnFindPort(unsigned int ProfileID, long PortNumber, int Protocol);
int mnPortExist(unsigned int ProfileID, long PortNumber, int Protocol);
unsigned int mnGetPortAmount(unsigned int ProfileID);
const char * mnGetApplicationName(unsigned int ProfileID, unsigned int ApplicationID);
const char * mnGetApplicationFileName(unsigned int ProfileID, unsigned int ApplicationID);
int mnGetApplicationIPVersion(unsigned int ProfileID, unsigned int ApplicationID);
int mnGetApplicationScope(unsigned int ProfileID, unsigned int ApplicationID);
const char * mnGetApplicationRemoteAddresses(unsigned int ProfileID, unsigned int ApplicationID);
int mnGetApplicationEnabled(unsigned int ProfileID, unsigned int ApplicationID);
int mnSetApplicationName(unsigned int ProfileID, unsigned int ApplicationID, char * Name);
int mnSetApplicationFileName(unsigned int ProfileID, unsigned int ApplicationID, char * FileName);
int mnSetApplicationIPVersion(unsigned int ProfileID, unsigned int ApplicationID, int IPVersion);
int mnSetApplicationScope(unsigned int ProfileID, unsigned int ApplicationID, int Scope);
int mnSetApplicationRemoteAddresses(unsigned int ProfileID, unsigned int ApplicationID, char * RemoteAddresses);
int mnSetApplicationEnabled(unsigned int ProfileID, unsigned int ApplicationID, bool Enabled);
Sound Input/Output Commands
Roughly 50 new sound input/output commands have been added which allow sound data to be input, sent and played. This facilitates voice communication.
Command list:
int mnStartSound(int NoInputInstances, int NoOutputInstances);
int mnFinishSound();
int mnGetNumInputInstances();
int mnGetNumOutputInstances();
int mnStartOutput(int InstanceID, unsigned int OutputDevice);
int mnFinishOutput(int InstanceID);
int mnPlayData(int InstanceID, long long int Packet);
int mnSetOutputSmoothValues(int InstanceID, unsigned int MillisecondsOfStoredDataCap, unsigned int TimeSinceLastAddedCap);
int mnSetOutputFormat(int InstanceID, unsigned short Channels, unsigned int SamplesPerSec, unsigned short BitsPerSample);
int mnSetOutputFormatHigh(int InstanceID);
int mnSetOutputFormatMedium(int InstanceID);
int mnSetOutputFormatLow(int InstanceID);
int mnSetDataVolume(unsigned short BitsPerSample, long long int Packet, int PercentageChange);
int mnGetDataVolume(unsigned short BitsPerSample, long long int Packet);
unsigned short mnGetOutputChannels(int InstanceID);
unsigned int mnGetOutputSamplesPerSec(int InstanceID);
unsigned short mnGetOutputBitsPerSample(int InstanceID);
unsigned int mnGetOutputStoredDataCap(int InstanceID);
unsigned int mnGetOutputLastAddedCap(int InstanceID);
double mnGetHardwarePlaybackRate(int InstanceID);
double mnGetHardwarePitch(int InstanceID);
unsigned short mnGetHardwareVolumeLeft(int InstanceID);
unsigned short mnGetHardwareVolumeRight(int InstanceID);
int mnSetHardwarePlaybackRate(int InstanceID, double Rate);
int mnSetHardwarePitch(int InstanceID, double Pitch);
int mnSetHardwareVolume(int InstanceID, unsigned short Left, unsigned short Right);
int mnStartInput(int InstanceID, unsigned int InputDevice);
int mnFinishInput(int InstanceID);
int mnPauseInput(int InstanceID);
int mnUnpauseInput(int InstanceID);
int mnGetInputData(int InstanceID, long long int Packet);
int mnGetInputUnpaused(int InstanceID);
int mnGetInputPaused(int InstanceID);
int mnSetInputSmoothValues(int InstanceID, unsigned int NoBuffers, unsigned int TimePerBuffer);
int mnSetInputFormat(int InstanceID, unsigned short Channels, unsigned int SamplesPerSec, unsigned short BitsPerSample);
int mnSetInputFormatHigh(int InstanceID);
int mnSetInputFormatMedium(int InstanceID);
int mnSetInputFormatLow(int InstanceID);
unsigned short mnGetInputChannels(int InstanceID);
unsigned int mnGetInputSamplesPerSec(int InstanceID);
unsigned short mnGetInputBitsPerSample(int InstanceID);
unsigned int mnGetInputNoBuffers(int InstanceID);
unsigned int mnGetInputTimePerBuffer(int InstanceID);
unsigned int mnGetNumInputDevices();
unsigned int mnGetNumOutputDevices();
unsigned short mnGetDeviceManuID(unsigned int DeviceID, bool Output);
unsigned short mnGetDeviceProductID(unsigned int DeviceID, bool Output);
unsigned char mnGetDeviceDriverMinorVersion(unsigned int DeviceID, bool Output);
unsigned char mnGetDeviceDriverMajorVersion(unsigned int DeviceID, bool Output);
const char * mnGetDeviceName(unsigned int DeviceID, bool Output);
unsigned int mnGetDeviceFormatSupport(unsigned int DeviceID, bool Output);
int mnReadDeviceFormatSupport(unsigned int SupportInfo, unsigned char KHZ, unsigned char Channels, unsigned char Bits);
unsigned short mnGetDeviceMaxChannels(unsigned int DeviceID, bool Output);
int mnGetDeviceHardwareSupport(unsigned int OutputDeviceID, unsigned int Feature);