You've already forked lidgren-network-gen3
mirror of
https://github.com/lidgren/lidgren-network-gen3.git
synced 2026-05-15 22:56:30 +09:00
Added NetConnection.CanSendImmediately() to determine if the sliding window is full
Recycle outgoing dropped messages Encryption using CryptoProviders refactored Added NetUnreliableSizeBehaviour to configure behaviour for unreliable messages above MTU Debug stats show number of received fragments
This commit is contained in:
@@ -1,180 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// AES encryption
|
||||
/// </summary>
|
||||
public class NetAESEncryption : NetEncryption
|
||||
public class NetAESEncryption : NetCryptoProviderBase
|
||||
{
|
||||
private readonly byte[] m_key;
|
||||
private readonly byte[] m_iv;
|
||||
private readonly int m_bitSize;
|
||||
private static readonly List<int> s_keysizes;
|
||||
private static readonly List<int> s_blocksizes;
|
||||
|
||||
static NetAESEncryption()
|
||||
public NetAESEncryption(NetPeer peer)
|
||||
: base(peer, new AesCryptoServiceProvider())
|
||||
{
|
||||
#if !IOS && !__ANDROID__ && !UNITY_4_5
|
||||
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
|
||||
List<int> temp = new List<int>();
|
||||
foreach (KeySizes keysize in aes.LegalKeySizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_keysizes = temp;
|
||||
temp = new List<int>();
|
||||
foreach (KeySizes keysize in aes.LegalBlockSizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_blocksizes = temp;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetAESEncryption constructor
|
||||
/// </summary>
|
||||
public NetAESEncryption(NetPeer peer, byte[] key, byte[] iv)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(key.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
if (!s_blocksizes.Contains(iv.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
|
||||
|
||||
m_key = key;
|
||||
m_iv = iv;
|
||||
m_bitSize = m_key.Length * 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetAESEncryption constructor
|
||||
/// </summary>
|
||||
public NetAESEncryption(NetPeer peer, string key, int bitsize)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(bitsize))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
byte[] entropy = Encoding.UTF32.GetBytes(key);
|
||||
// I know hardcoding salts is bad, but in this case I think it is acceptable.
|
||||
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
|
||||
hmacsha512.Initialize();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
entropy = hmacsha512.ComputeHash(entropy);
|
||||
}
|
||||
int keylen = bitsize / 8;
|
||||
m_key = new byte[keylen];
|
||||
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
|
||||
m_iv = new byte[s_blocksizes[0] / 8];
|
||||
|
||||
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
|
||||
m_bitSize = bitsize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetAESEncryption constructor
|
||||
/// </summary>
|
||||
public NetAESEncryption(NetPeer peer, string key)
|
||||
: this(peer, key, s_keysizes[0])
|
||||
: base(peer, new AesCryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt outgoing message
|
||||
/// </summary>
|
||||
public override bool Encrypt(NetOutgoingMessage msg)
|
||||
public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new AesCryptoServiceProvider())
|
||||
{
|
||||
#if !IOS && !__ANDROID__ && !UNITY_4_5
|
||||
try
|
||||
{
|
||||
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Encryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt incoming message
|
||||
/// </summary>
|
||||
public override bool Decrypt(NetIncomingMessage msg)
|
||||
{
|
||||
#if !IOS && !__ANDROID__ && !UNITY_4_5
|
||||
try
|
||||
{
|
||||
// nested usings are fun!
|
||||
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Decryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,170 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// DES encryption
|
||||
/// </summary>
|
||||
public class NetDESEncryption : NetEncryption
|
||||
public class NetDESEncryption : NetCryptoProviderBase
|
||||
{
|
||||
private readonly byte[] m_key;
|
||||
private readonly byte[] m_iv;
|
||||
private readonly int m_bitSize;
|
||||
private static readonly List<int> s_keysizes;
|
||||
private static readonly List<int> s_blocksizes;
|
||||
|
||||
static NetDESEncryption()
|
||||
public NetDESEncryption(NetPeer peer)
|
||||
: base(peer, new DESCryptoServiceProvider())
|
||||
{
|
||||
|
||||
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
|
||||
List<int> temp = new List<int>();
|
||||
foreach (KeySizes keysize in des.LegalKeySizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_keysizes = temp;
|
||||
temp = new List<int>();
|
||||
foreach (KeySizes keysize in des.LegalBlockSizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_blocksizes = temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetDESEncryption constructor
|
||||
/// </summary>
|
||||
public NetDESEncryption(NetPeer peer, byte[] key, byte[] iv)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(key.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
if (!s_blocksizes.Contains(iv.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
|
||||
|
||||
m_key = key;
|
||||
m_iv = iv;
|
||||
m_bitSize = m_key.Length * 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetDESEncryption constructor
|
||||
/// </summary>
|
||||
public NetDESEncryption(NetPeer peer, string key, int bitsize)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(bitsize))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
byte[] entropy = Encoding.UTF32.GetBytes(key);
|
||||
// I know hardcoding salts is bad, but in this case I think it is acceptable.
|
||||
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
|
||||
hmacsha512.Initialize();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
entropy = hmacsha512.ComputeHash(entropy);
|
||||
}
|
||||
int keylen = bitsize / 8;
|
||||
m_key = new byte[keylen];
|
||||
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
|
||||
m_iv = new byte[s_blocksizes[0] / 8];
|
||||
|
||||
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
|
||||
m_bitSize = bitsize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetDESEncryption constructor
|
||||
/// </summary>
|
||||
public NetDESEncryption(NetPeer peer, string key)
|
||||
: this(peer, key, s_keysizes[0])
|
||||
: base(peer, new DESCryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt outgoing message
|
||||
/// </summary>
|
||||
public override bool Encrypt(NetOutgoingMessage msg)
|
||||
public NetDESEncryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new DESCryptoServiceProvider())
|
||||
{
|
||||
try
|
||||
{
|
||||
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Encryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt incoming message
|
||||
/// </summary>
|
||||
public override bool Decrypt(NetIncomingMessage msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Decryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
@@ -23,6 +24,14 @@ namespace Lidgren.Network
|
||||
m_peer = peer;
|
||||
}
|
||||
|
||||
public void SetKey(string str)
|
||||
{
|
||||
var bytes = System.Text.Encoding.ASCII.GetBytes(str);
|
||||
SetKey(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
public abstract void SetKey(byte[] data, int offset, int count);
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt an outgoing message in place
|
||||
/// </summary>
|
||||
|
||||
@@ -1,173 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// RC2 encryption
|
||||
/// </summary>
|
||||
public class NetRC2Encryption : NetEncryption
|
||||
public class NetRC2Encryption : NetCryptoProviderBase
|
||||
{
|
||||
private readonly byte[] m_key;
|
||||
private readonly byte[] m_iv;
|
||||
private readonly int m_bitSize;
|
||||
private static readonly List<int> s_keysizes;
|
||||
private static readonly List<int> s_blocksizes;
|
||||
|
||||
static NetRC2Encryption()
|
||||
public NetRC2Encryption(NetPeer peer)
|
||||
: base(peer, new RC2CryptoServiceProvider())
|
||||
{
|
||||
|
||||
RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
|
||||
List<int> temp = new List<int>();
|
||||
foreach (KeySizes keysize in rc2.LegalKeySizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_keysizes = temp;
|
||||
temp = new List<int>();
|
||||
foreach (KeySizes keysize in rc2.LegalBlockSizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_blocksizes = temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetRC2Encryption constructor
|
||||
/// </summary>
|
||||
public NetRC2Encryption(NetPeer peer, byte[] key, byte[] iv)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(key.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
if (!s_blocksizes.Contains(iv.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
|
||||
|
||||
m_key = key;
|
||||
m_iv = iv;
|
||||
m_bitSize = m_key.Length * 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetRC2Encryption constructor
|
||||
/// </summary>
|
||||
public NetRC2Encryption(NetPeer peer, string key, int bitsize)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(bitsize))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
byte[] entropy = Encoding.UTF32.GetBytes(key);
|
||||
// I know hardcoding salts is bad, but in this case I think it is acceptable.
|
||||
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
|
||||
hmacsha512.Initialize();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
entropy = hmacsha512.ComputeHash(entropy);
|
||||
}
|
||||
int keylen = bitsize / 8;
|
||||
m_key = new byte[keylen];
|
||||
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
|
||||
m_iv = new byte[s_blocksizes[0] / 8];
|
||||
|
||||
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
|
||||
m_bitSize = bitsize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetRC2Encryption constructor
|
||||
/// </summary>
|
||||
/// <param name="peer"></param>
|
||||
/// <param name="key"></param>
|
||||
public NetRC2Encryption(NetPeer peer, string key)
|
||||
: this(peer, key, s_keysizes[0])
|
||||
: base(peer, new RC2CryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt outgoing message
|
||||
/// </summary>
|
||||
public override bool Encrypt(NetOutgoingMessage msg)
|
||||
public NetRC2Encryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new RC2CryptoServiceProvider())
|
||||
{
|
||||
try
|
||||
{
|
||||
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateEncryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Encryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt incoming message
|
||||
/// </summary>
|
||||
public override bool Decrypt(NetIncomingMessage msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
// nested usings are fun!
|
||||
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateDecryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Decryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,170 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Lidgren.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Triple DES encryption
|
||||
/// </summary>
|
||||
public class NetTripleDESEncryption : NetEncryption
|
||||
public class NetTripleDESEncryption : NetCryptoProviderBase
|
||||
{
|
||||
private readonly byte[] m_key;
|
||||
private readonly byte[] m_iv;
|
||||
private readonly int m_bitSize;
|
||||
private static readonly List<int> s_keysizes;
|
||||
private static readonly List<int> s_blocksizes;
|
||||
|
||||
static NetTripleDESEncryption()
|
||||
public NetTripleDESEncryption(NetPeer peer)
|
||||
: base(peer, new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
|
||||
List<int> temp = new List<int>();
|
||||
foreach (KeySizes keysize in tripleDES.LegalKeySizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_keysizes = temp;
|
||||
temp = new List<int>();
|
||||
foreach (KeySizes keysize in tripleDES.LegalBlockSizes)
|
||||
{
|
||||
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
|
||||
{
|
||||
|
||||
if (!temp.Contains(i))
|
||||
temp.Add(i);
|
||||
if (i == keysize.MaxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_blocksizes = temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetTriplsDESEncryption constructor
|
||||
/// </summary>
|
||||
public NetTripleDESEncryption(NetPeer peer, byte[] key, byte[] iv)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(key.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
if (!s_blocksizes.Contains(iv.Length * 8))
|
||||
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
|
||||
|
||||
m_key = key;
|
||||
m_iv = iv;
|
||||
m_bitSize = m_key.Length * 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetTriplsDESEncryption constructor
|
||||
/// </summary>
|
||||
public NetTripleDESEncryption(NetPeer peer, string key, int bitsize)
|
||||
: base(peer)
|
||||
{
|
||||
if (!s_keysizes.Contains(bitsize))
|
||||
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
|
||||
|
||||
byte[] entropy = Encoding.UTF32.GetBytes(key);
|
||||
// I know hardcoding salts is bad, but in this case I think it is acceptable.
|
||||
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
|
||||
hmacsha512.Initialize();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
entropy = hmacsha512.ComputeHash(entropy);
|
||||
}
|
||||
int keylen = bitsize / 8;
|
||||
m_key = new byte[keylen];
|
||||
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
|
||||
m_iv = new byte[s_blocksizes[0] / 8];
|
||||
|
||||
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
|
||||
m_bitSize = bitsize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetTriplsDESEncryption constructor
|
||||
/// </summary>
|
||||
public NetTripleDESEncryption(NetPeer peer, string key)
|
||||
: this(peer, key, s_keysizes[0])
|
||||
: base(peer, new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt outgoing message
|
||||
/// </summary>
|
||||
public override bool Encrypt(NetOutgoingMessage msg)
|
||||
public NetTripleDESEncryption(NetPeer peer, byte[] data, int offset, int count)
|
||||
: base(peer, new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Encryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypt incoming message
|
||||
/// </summary>
|
||||
public override bool Decrypt(NetIncomingMessage msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
// nested usings are fun!
|
||||
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
|
||||
{
|
||||
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
|
||||
cryptoStream.Close();
|
||||
|
||||
m_peer.Recycle(msg.m_data);
|
||||
var arr = memoryStream.ToArray();
|
||||
msg.m_data = arr;
|
||||
msg.m_bitLength = arr.Length * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_peer.LogWarning("Decryption failed: " + ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
SetKey(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ namespace Lidgren.Network
|
||||
m_key = key;
|
||||
}
|
||||
|
||||
public override void SetKey(byte[] data, int offset, int count)
|
||||
{
|
||||
m_key = new byte[count];
|
||||
Array.Copy(data, offset, m_key, 0, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetXorEncryption constructor
|
||||
/// </summary>
|
||||
|
||||
@@ -87,6 +87,13 @@ namespace Lidgren.Network
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetKey(byte[] data, int offset, int length)
|
||||
{
|
||||
var key = NetUtility.CreateSHA1Hash(data, offset, length);
|
||||
NetException.Assert(key.Length == 16);
|
||||
SetKey(key, 0, 16);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypts a block of bytes
|
||||
/// </summary>
|
||||
|
||||
@@ -59,12 +59,15 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Encryption\NetEncryption.cs" />
|
||||
<Compile Include="Encryption\NetAESEncryption.cs" />
|
||||
<Compile Include="Encryption\NetBlockEncryptionBase.cs" />
|
||||
<Compile Include="Encryption\NetAESEncryption.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Encryption\NetCryptoProviderBase.cs" />
|
||||
<Compile Include="Encryption\NetDESEncryption.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Encryption\NetEncryption.cs" />
|
||||
<Compile Include="Encryption\NetBlockEncryptionBase.cs" />
|
||||
<Compile Include="Encryption\NetRC2Encryption.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace Lidgren.Network
|
||||
|
||||
internal int m_currentMTU;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current MTU in bytes. If PeerConfiguration.AutoExpandMTU is false, this will be PeerConfiguration.MaximumTransmissionUnit.
|
||||
/// </summary>
|
||||
public int CurrentMTU { get { return m_currentMTU; } }
|
||||
|
||||
internal void InitExpandMTU(double now)
|
||||
{
|
||||
m_lastSentMTUAttemptTime = now + m_peerConfiguration.m_expandMTUFrequency + 1.5f + m_averageRoundtripTime; // wait a tiny bit before starting to expand mtu
|
||||
@@ -150,7 +155,7 @@ namespace Lidgren.Network
|
||||
bool connectionReset;
|
||||
m_peer.SendPacket(len, m_remoteEndPoint, 1, out connectionReset);
|
||||
|
||||
// m_peer.LogDebug("Received MTU expand request for " + size + " bytes");
|
||||
//m_peer.LogDebug("Received MTU expand request for " + size + " bytes");
|
||||
|
||||
m_statistics.PacketSent(len, 1);
|
||||
}
|
||||
|
||||
@@ -279,24 +279,36 @@ namespace Lidgren.Network
|
||||
m_peer.VerifyNetworkThread();
|
||||
|
||||
int sz = om.GetEncodedSize();
|
||||
if (sz > m_currentMTU)
|
||||
m_peer.LogWarning("Message larger than MTU! Fragmentation must have failed!");
|
||||
//if (sz > m_currentMTU)
|
||||
// m_peer.LogWarning("Message larger than MTU! Fragmentation must have failed!");
|
||||
|
||||
bool connReset; // TODO: handle connection reset
|
||||
|
||||
// can fit this message together with previously written to buffer?
|
||||
if (m_sendBufferWritePtr + sz > m_currentMTU)
|
||||
{
|
||||
bool connReset; // TODO: handle connection reset
|
||||
NetException.Assert(m_sendBufferWritePtr > 0 && m_sendBufferNumMessages > 0); // or else the message should have been fragmented earlier
|
||||
if (m_sendBufferWritePtr > 0 && m_sendBufferNumMessages > 0)
|
||||
{
|
||||
// previous message in buffer; send these first
|
||||
m_peer.SendPacket(m_sendBufferWritePtr, m_remoteEndPoint, m_sendBufferNumMessages, out connReset);
|
||||
m_statistics.PacketSent(m_sendBufferWritePtr, m_sendBufferNumMessages);
|
||||
m_sendBufferWritePtr = 0;
|
||||
m_sendBufferNumMessages = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// encode it into buffer regardless if it (now) fits within MTU or not
|
||||
m_sendBufferWritePtr = om.Encode(m_peer.m_sendBuffer, m_sendBufferWritePtr, seqNr);
|
||||
m_sendBufferNumMessages++;
|
||||
|
||||
if (m_sendBufferWritePtr > m_currentMTU)
|
||||
{
|
||||
// send immediately; we're already over MTU
|
||||
m_peer.SendPacket(m_sendBufferWritePtr, m_remoteEndPoint, m_sendBufferNumMessages, out connReset);
|
||||
m_statistics.PacketSent(m_sendBufferWritePtr, m_sendBufferNumMessages);
|
||||
m_sendBufferWritePtr = 0;
|
||||
m_sendBufferNumMessages = 0;
|
||||
}
|
||||
|
||||
m_sendBufferWritePtr = om.Encode(m_peer.m_sendBuffer, m_sendBufferWritePtr, seqNr);
|
||||
m_sendBufferNumMessages++;
|
||||
|
||||
NetException.Assert(m_sendBufferWritePtr > 0, "Encoded zero size message?");
|
||||
NetException.Assert(m_sendBufferNumMessages > 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -325,12 +337,12 @@ namespace Lidgren.Network
|
||||
if (chan == null)
|
||||
chan = CreateSenderChannel(tp);
|
||||
|
||||
if (msg.GetEncodedSize() > m_currentMTU)
|
||||
m_peer.ThrowOrLog("Message too large! Fragmentation failure?");
|
||||
if ((method != NetDeliveryMethod.Unreliable && method != NetDeliveryMethod.UnreliableSequenced) && msg.GetEncodedSize() > m_currentMTU)
|
||||
m_peer.ThrowOrLog("Reliable message too large! Fragmentation failure?");
|
||||
|
||||
var retval = chan.Enqueue(msg);
|
||||
if (retval == NetSendResult.Sent && m_peerConfiguration.m_autoFlushSendQueue == false)
|
||||
retval = NetSendResult.Queued; // queued since we're not autoflushing
|
||||
//if (retval == NetSendResult.Sent && m_peerConfiguration.m_autoFlushSendQueue == false)
|
||||
// retval = NetSendResult.Queued; // queued since we're not autoflushing
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -522,6 +534,15 @@ namespace Lidgren.Network
|
||||
return;
|
||||
}
|
||||
|
||||
public bool CanSendImmediately(NetDeliveryMethod method, int sequenceChannel)
|
||||
{
|
||||
int channelSlot = (int)method - 1 + sequenceChannel;
|
||||
var chan = m_sendChannels[channelSlot];
|
||||
if (chan == null)
|
||||
return true;
|
||||
return (chan.GetAllowedSends() - chan.m_queuedSends.Count) > 0;
|
||||
}
|
||||
|
||||
internal void Shutdown(string reason)
|
||||
{
|
||||
ExecuteDisconnect(reason, true);
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace Lidgren.Network
|
||||
|
||||
internal int m_sentMessages;
|
||||
internal int m_receivedMessages;
|
||||
internal int m_receivedFragments;
|
||||
|
||||
internal int m_sentBytes;
|
||||
internal int m_receivedBytes;
|
||||
@@ -62,8 +63,13 @@ namespace Lidgren.Network
|
||||
{
|
||||
m_sentPackets = 0;
|
||||
m_receivedPackets = 0;
|
||||
m_sentMessages = 0;
|
||||
m_receivedMessages = 0;
|
||||
m_receivedFragments = 0;
|
||||
m_sentBytes = 0;
|
||||
m_receivedBytes = 0;
|
||||
m_resentMessagesDueToDelay = 0;
|
||||
m_resentMessagesDueToHole = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -122,12 +128,13 @@ namespace Lidgren.Network
|
||||
}
|
||||
#else
|
||||
[Conditional("DEBUG")]
|
||||
internal void PacketReceived(int numBytes, int numMessages)
|
||||
internal void PacketReceived(int numBytes, int numMessages, int numFragments)
|
||||
{
|
||||
NetException.Assert(numBytes > 0 && numMessages > 0);
|
||||
m_receivedPackets++;
|
||||
m_receivedBytes += numBytes;
|
||||
m_receivedMessages += numMessages;
|
||||
m_receivedFragments += numFragments;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -157,8 +164,9 @@ namespace Lidgren.Network
|
||||
{
|
||||
StringBuilder bdr = new StringBuilder();
|
||||
//bdr.AppendLine("Average roundtrip time: " + NetTime.ToReadable(m_connection.m_averageRoundtripTime));
|
||||
bdr.AppendLine("Current MTU: " + m_connection.m_currentMTU);
|
||||
bdr.AppendLine("Sent " + m_sentBytes + " bytes in " + m_sentMessages + " messages in " + m_sentPackets + " packets");
|
||||
bdr.AppendLine("Received " + m_receivedBytes + " bytes in " + m_receivedMessages + " messages in " + m_receivedPackets + " packets");
|
||||
bdr.AppendLine("Received " + m_receivedBytes + " bytes in " + m_receivedMessages + " messages (of which " + m_receivedFragments + " fragments) in " + m_receivedPackets + " packets");
|
||||
|
||||
if (m_resentMessagesDueToDelay > 0)
|
||||
bdr.AppendLine("Resent messages (delay): " + m_resentMessagesDueToDelay);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Lidgren.Network
|
||||
private Dictionary<NetConnection, Dictionary<int, ReceivedFragmentGroup>> m_receivedFragmentGroups;
|
||||
|
||||
// on user thread
|
||||
private void SendFragmentedMessage(NetOutgoingMessage msg, IList<NetConnection> recipients, NetDeliveryMethod method, int sequenceChannel)
|
||||
private NetSendResult SendFragmentedMessage(NetOutgoingMessage msg, IList<NetConnection> recipients, NetDeliveryMethod method, int sequenceChannel)
|
||||
{
|
||||
// Note: this group id is PER SENDING/NetPeer; ie. same id is sent to all recipients;
|
||||
// this should be ok however; as long as recipients differentiate between same id but different sender
|
||||
@@ -44,6 +44,8 @@ namespace Lidgren.Network
|
||||
if (numChunks * bytesPerChunk < totalBytes)
|
||||
numChunks++;
|
||||
|
||||
NetSendResult retval = NetSendResult.Sent;
|
||||
|
||||
int bitsPerChunk = bytesPerChunk * 8;
|
||||
int bitsLeft = msg.LengthBits;
|
||||
for (int i = 0; i < numChunks; i++)
|
||||
@@ -63,12 +65,16 @@ namespace Lidgren.Network
|
||||
Interlocked.Add(ref chunk.m_recyclingCount, recipients.Count);
|
||||
|
||||
foreach (NetConnection recipient in recipients)
|
||||
recipient.EnqueueMessage(chunk, method, sequenceChannel);
|
||||
{
|
||||
var res = recipient.EnqueueMessage(chunk, method, sequenceChannel);
|
||||
if ((int)res > (int)retval)
|
||||
retval = res; // return "worst" result
|
||||
}
|
||||
|
||||
bitsLeft -= bitsPerChunk;
|
||||
}
|
||||
|
||||
return;
|
||||
return retval;
|
||||
}
|
||||
|
||||
private void HandleReleasedFragment(NetIncomingMessage im)
|
||||
|
||||
@@ -99,7 +99,16 @@ namespace Lidgren.Network
|
||||
if (m_receiveCallbacks != null)
|
||||
{
|
||||
foreach (var tuple in m_receiveCallbacks)
|
||||
tuple.Item1.Post(tuple.Item2, this);
|
||||
{
|
||||
try
|
||||
{
|
||||
tuple.Item1.Post(tuple.Item2, this);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogWarning("Receive callback exception:" + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,6 +482,7 @@ namespace Lidgren.Network
|
||||
// parse packet into messages
|
||||
//
|
||||
int numMessages = 0;
|
||||
int numFragments = 0;
|
||||
int ptr = 0;
|
||||
while ((bytesReceived - ptr) >= NetConstants.HeaderByteSize)
|
||||
{
|
||||
@@ -492,6 +502,8 @@ namespace Lidgren.Network
|
||||
bool isFragment = ((low & 1) == 1);
|
||||
ushort sequenceNumber = (ushort)((low >> 1) | (((int)high) << 7));
|
||||
|
||||
numFragments++;
|
||||
|
||||
ushort payloadBitLength = (ushort)(m_receiveBuffer[ptr++] | (m_receiveBuffer[ptr++] << 8));
|
||||
int payloadByteLength = NetUtility.BytesToHoldBits(payloadBitLength);
|
||||
|
||||
@@ -561,9 +573,9 @@ namespace Lidgren.Network
|
||||
ptr += payloadByteLength;
|
||||
}
|
||||
|
||||
m_statistics.PacketReceived(bytesReceived, numMessages);
|
||||
m_statistics.PacketReceived(bytesReceived, numMessages, numFragments);
|
||||
if (sender != null)
|
||||
sender.m_statistics.PacketReceived(bytesReceived, numMessages);
|
||||
sender.m_statistics.PacketReceived(bytesReceived, numMessages, numFragments);
|
||||
|
||||
} while (m_socket.Available > 0);
|
||||
}
|
||||
|
||||
@@ -46,8 +46,10 @@ namespace Lidgren.Network
|
||||
throw new NetException("This message has already been sent! Use NetPeer.SendMessage() to send to multiple recipients efficiently");
|
||||
msg.m_isSent = true;
|
||||
|
||||
bool suppressFragmentation = (method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.UnreliableSequenced) && m_configuration.UnreliableSizeBehaviour != NetUnreliableSizeBehaviour.NormalFragmentation;
|
||||
|
||||
int len = NetConstants.UnfragmentedMessageHeaderSize + msg.LengthBytes; // headers + length, faster than calling msg.GetEncodedSize
|
||||
if (len <= recipient.m_currentMTU)
|
||||
if (len <= recipient.m_currentMTU || suppressFragmentation)
|
||||
{
|
||||
Interlocked.Increment(ref msg.m_recyclingCount);
|
||||
return recipient.EnqueueMessage(msg, method, sequenceChannel);
|
||||
@@ -57,8 +59,7 @@ namespace Lidgren.Network
|
||||
// message must be fragmented!
|
||||
if (recipient.m_status != NetConnectionStatus.Connected)
|
||||
return NetSendResult.FailedNotConnected;
|
||||
SendFragmentedMessage(msg, new NetConnection[] { recipient }, method, sequenceChannel);
|
||||
return NetSendResult.Queued; // could be different for each connection; Queued is "most true"
|
||||
return SendFragmentedMessage(msg, new NetConnection[] { recipient }, method, sequenceChannel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace Lidgren.Network
|
||||
internal float m_connectionTimeout;
|
||||
internal bool m_enableUPnP;
|
||||
internal bool m_autoFlushSendQueue;
|
||||
private NetUnreliableSizeBehaviour m_unreliableSizeBehaviour;
|
||||
|
||||
internal NetIncomingMessageType m_disabledTypes;
|
||||
internal int m_port;
|
||||
@@ -114,6 +115,7 @@ namespace Lidgren.Network
|
||||
m_autoExpandMTU = false;
|
||||
m_expandMTUFrequency = 2.0f;
|
||||
m_expandMTUFailAttempts = 5;
|
||||
m_unreliableSizeBehaviour = NetUnreliableSizeBehaviour.IgnoreMTU;
|
||||
|
||||
m_loss = 0.0f;
|
||||
m_minimumOneWayLatency = 0.0f;
|
||||
@@ -171,6 +173,15 @@ namespace Lidgren.Network
|
||||
return !((m_disabledTypes & type) == type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the behaviour of unreliable sends above MTU
|
||||
/// </summary>
|
||||
public NetUnreliableSizeBehaviour UnreliableSizeBehaviour
|
||||
{
|
||||
get { return m_unreliableSizeBehaviour; }
|
||||
set { m_unreliableSizeBehaviour = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the library network thread. Cannot be changed once NetPeer is initialized.
|
||||
/// </summary>
|
||||
@@ -474,4 +485,25 @@ namespace Lidgren.Network
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Behaviour of unreliable sends above MTU
|
||||
/// </summary>
|
||||
public enum NetUnreliableSizeBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Sending an unreliable message will ignore MTU and send everything in a single packet; this is the new default
|
||||
/// </summary>
|
||||
IgnoreMTU = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Old behaviour; use normal fragmentation for unreliable messages - if a fragment is dropped, memory for received fragments are never reclaimed!
|
||||
/// </summary>
|
||||
NormalFragmentation = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Alternate behaviour; just drops unreliable messages above MTU
|
||||
/// </summary>
|
||||
DropAboveMTU = 2,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace Lidgren.Network
|
||||
|
||||
internal int m_sentMessages;
|
||||
internal int m_receivedMessages;
|
||||
internal int m_receivedFragments;
|
||||
|
||||
internal int m_sentBytes;
|
||||
internal int m_receivedBytes;
|
||||
@@ -58,6 +59,7 @@ namespace Lidgren.Network
|
||||
|
||||
m_sentMessages = 0;
|
||||
m_receivedMessages = 0;
|
||||
m_receivedFragments = 0;
|
||||
|
||||
m_sentBytes = 0;
|
||||
m_receivedBytes = 0;
|
||||
@@ -131,11 +133,12 @@ namespace Lidgren.Network
|
||||
}
|
||||
#else
|
||||
[Conditional("DEBUG")]
|
||||
internal void PacketReceived(int numBytes, int numMessages)
|
||||
internal void PacketReceived(int numBytes, int numMessages, int numFragments)
|
||||
{
|
||||
m_receivedPackets++;
|
||||
m_receivedBytes += numBytes;
|
||||
m_receivedMessages += numMessages;
|
||||
m_receivedFragments += numFragments;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -148,7 +151,7 @@ namespace Lidgren.Network
|
||||
bdr.AppendLine(m_peer.ConnectionsCount.ToString() + " connections");
|
||||
#if DEBUG || USE_RELEASE_STATISTICS
|
||||
bdr.AppendLine("Sent " + m_sentBytes + " bytes in " + m_sentMessages + " messages in " + m_sentPackets + " packets");
|
||||
bdr.AppendLine("Received " + m_receivedBytes + " bytes in " + m_receivedMessages + " messages in " + m_receivedPackets + " packets");
|
||||
bdr.AppendLine("Received " + m_receivedBytes + " bytes in " + m_receivedMessages + " messages (of which " + m_receivedFragments + " fragments) in " + m_receivedPackets + " packets");
|
||||
#else
|
||||
bdr.AppendLine("Sent (n/a) bytes in (n/a) messages in (n/a) packets");
|
||||
bdr.AppendLine("Received (n/a) bytes in (n/a) messages in (n/a) packets");
|
||||
|
||||
@@ -46,8 +46,11 @@ namespace Lidgren.Network
|
||||
{
|
||||
int queueLen = m_queuedSends.Count + 1;
|
||||
int left = GetAllowedSends();
|
||||
if (queueLen > left)
|
||||
if (queueLen > left || (message.LengthBytes > m_connection.m_currentMTU && m_connection.m_peerConfiguration.UnreliableSizeBehaviour == NetUnreliableSizeBehaviour.DropAboveMTU))
|
||||
{
|
||||
m_connection.Peer.Recycle(message);
|
||||
return NetSendResult.Dropped;
|
||||
}
|
||||
|
||||
m_queuedSends.Enqueue(message);
|
||||
return NetSendResult.Sent;
|
||||
|
||||
@@ -263,13 +263,21 @@ namespace Lidgren.Network
|
||||
/// </summary>
|
||||
public static string ToHexString(byte[] data)
|
||||
{
|
||||
char[] c = new char[data.Length * 2];
|
||||
return ToHexString(data, 0, data.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a hex string from an array of bytes
|
||||
/// </summary>
|
||||
public static string ToHexString(byte[] data, int offset, int length)
|
||||
{
|
||||
char[] c = new char[length * 2];
|
||||
byte b;
|
||||
for (int i = 0; i < data.Length; ++i)
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
b = ((byte)(data[i] >> 4));
|
||||
b = ((byte)(data[offset + i] >> 4));
|
||||
c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30);
|
||||
b = ((byte)(data[i] & 0xF));
|
||||
b = ((byte)(data[offset + i] & 0xF));
|
||||
c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30);
|
||||
}
|
||||
return new string(c);
|
||||
@@ -611,5 +619,14 @@ namespace Lidgren.Network
|
||||
using (var sha = new SHA1CryptoServiceProvider())
|
||||
return sha.ComputeHash(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a SHA1 digest from a byte buffer
|
||||
/// </summary>
|
||||
public static byte[] CreateSHA1Hash(byte[] data, int offset, int count)
|
||||
{
|
||||
using (var sha = new SHA1CryptoServiceProvider())
|
||||
return sha.ComputeHash(data, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,6 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
|
||||
@@ -26,9 +26,7 @@ namespace FileStreamServer
|
||||
if (m_inputStream == null)
|
||||
return;
|
||||
|
||||
int windowSize, freeWindowSlots;
|
||||
m_connection.GetSendQueueInfo(NetDeliveryMethod.ReliableOrdered, 1, out windowSize, out freeWindowSlots);
|
||||
if (freeWindowSlots > 0)
|
||||
if (m_connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1))
|
||||
{
|
||||
// send another part of the file!
|
||||
long remaining = m_inputStream.Length - m_sentOffset;
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
|
||||
@@ -14,14 +14,14 @@ namespace UnitTests
|
||||
//
|
||||
// Test encryption
|
||||
//
|
||||
List<INetEncryption> algos = new List<INetEncryption>();
|
||||
List<NetEncryption> algos = new List<NetEncryption>();
|
||||
|
||||
algos.Add(new NetXorEncryption("TopSecret"));
|
||||
algos.Add(new NetXtea("TopSecret"));
|
||||
algos.Add(new NetAESEncryption("TopSecret"));
|
||||
algos.Add(new NetRC2Encryption("TopSecret"));
|
||||
algos.Add(new NetDESEncryption("TopSecret"));
|
||||
algos.Add(new NetTripleDESEncryption("TopSecret"));
|
||||
algos.Add(new NetXorEncryption(peer, "TopSecret"));
|
||||
algos.Add(new NetXtea(peer, "TopSecret"));
|
||||
algos.Add(new NetAESEncryption(peer, "TopSecret"));
|
||||
algos.Add(new NetRC2Encryption(peer, "TopSecret"));
|
||||
algos.Add(new NetDESEncryption(peer, "TopSecret"));
|
||||
algos.Add(new NetTripleDESEncryption(peer, "TopSecret"));
|
||||
|
||||
foreach (var algo in algos)
|
||||
{
|
||||
@@ -31,7 +31,7 @@ namespace UnitTests
|
||||
om.Write(5, 5);
|
||||
om.Write(true);
|
||||
om.Write("kokos");
|
||||
int trueLen = om.LengthBits;
|
||||
int unencLen = om.LengthBits;
|
||||
om.Encrypt(algo);
|
||||
|
||||
// convert to incoming message
|
||||
@@ -41,10 +41,11 @@ namespace UnitTests
|
||||
|
||||
im.Decrypt(algo);
|
||||
|
||||
if (im.Data == null || im.Data.Length == 0 || im.LengthBits != trueLen)
|
||||
if (im.Data == null || im.Data.Length == 0 || im.LengthBits != unencLen)
|
||||
throw new NetException("Length fail");
|
||||
|
||||
if (im.ReadString() != "Hallon")
|
||||
var str = im.ReadString();
|
||||
if (str != "Hallon")
|
||||
throw new NetException("fail");
|
||||
if (im.ReadInt32() != 42)
|
||||
throw new NetException("fail");
|
||||
@@ -92,7 +93,7 @@ namespace UnitTests
|
||||
throw new NetException("SRP non matching session values!");
|
||||
}
|
||||
|
||||
var test = NetSRP.CreateEncryption(Ss);
|
||||
var test = NetSRP.CreateEncryption(peer, Ss);
|
||||
}
|
||||
|
||||
Console.WriteLine("Message encryption OK");
|
||||
|
||||
Reference in New Issue
Block a user