forked from lidgren/lidgren-network-gen3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
26 changed files
with
217 additions
and
680 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
{ | ||
#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) | ||
public NetAESEncryption(NetPeer peer) | ||
: base(peer, new AesCryptoServiceProvider()) | ||
{ | ||
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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
{ | ||
|
||
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) | ||
public NetDESEncryption(NetPeer peer) | ||
: base(peer, new DESCryptoServiceProvider()) | ||
{ | ||
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]) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Encrypt outgoing message | ||
/// </summary> | ||
public override bool Encrypt(NetOutgoingMessage msg) | ||
: 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; | ||
SetKey(key); | ||
} | ||
|
||
/// <summary> | ||
/// Decrypt incoming message | ||
/// </summary> | ||
public override bool Decrypt(NetIncomingMessage 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.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); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.